[rygel-grilo] Handle Get call
- From: Juan A. Suarez Romero <jasuarez src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel-grilo] Handle Get call
- Date: Tue, 4 May 2010 10:28:39 +0000 (UTC)
commit 22cd6bb5c26849fa2b8a119ad7a254167a3aa4f6
Author: Juan A. Suarez Romero <jasuarez igalia com>
Date: Tue Apr 27 23:56:51 2010 +0200
Handle Get call
data/media-server2.xml | 18 ++--
lib/media-server2-common.h | 58 +++++------
lib/media-server2-server.c | 226 +++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 258 insertions(+), 44 deletions(-)
---
diff --git a/data/media-server2.xml b/data/media-server2.xml
index 011f937..22f2f10 100644
--- a/data/media-server2.xml
+++ b/data/media-server2.xml
@@ -13,24 +13,20 @@
</interface>
<interface name="org.gnome.UPnP.MediaItem2">
- <property name="URLs" type="as" access="read"/>
- <property name="MIMEType" type="s" access="read"/>
- <property name="Type" type="s" access="read"/>
- <property name="Artist" type="s" access="read"/>
<property name="Album" type="s" access="read"/>
- <property name="Genre" type="s" access="read"/>
- <property name="Duration" type="i" access="read"/>
+ <property name="Artist" type="s" access="read"/>
<property name="Bitrate" type="i" access="read"/>
- <property name="Width" type="i" access="read"/>
+ <property name="Duration" type="i" access="read"/>
+ <property name="Genre" type="s" access="read"/>
<property name="Height" type="i" access="read"/>
+ <property name="MIMEType" type="s" access="read"/>
+ <property name="Type" type="s" access="read"/>
+ <property name="URLs" type="as" access="read"/>
+ <property name="Width" type="i" access="read"/>
</interface>
<interface name="org.gnome.UPnP.MediaContainer2">
<property name="CanSearch" type="b" access="read"/>
- <property name="ContainerCount" type="u" access="read"/>
- <property name="Containers" type="ao" access="read"/>
- <property name="ItemCount" type="u" access="read"/>
- <property name="Items" type="ao" access="read"/>
<method name="ListObjects">
<arg name="offset" direction="in" type="u"/>
diff --git a/lib/media-server2-common.h b/lib/media-server2-common.h
index d791253..a3ff9b9 100644
--- a/lib/media-server2-common.h
+++ b/lib/media-server2-common.h
@@ -26,41 +26,35 @@
#define MS2_ERROR \
g_quark_from_static_string("media_server2_error")
-/* Common properties */
-#define MS2_PROP_ID "id"
-#define MS2_PROP_PARENT "parent"
-#define MS2_PROP_DISPLAY_NAME "display-name"
-#define MS2_PROP_TYPE "type"
+/* MediaObject2 properties */
+#define MS2_PROP_DISPLAY_NAME "DisplayName"
+#define MS2_PROP_PARENT "Parent"
+#define MS2_PROP_ID "Path"
-/* Container properties */
-#define MS2_PROP_CHILD_COUNT "child-count"
-#define MS2_PROP_ICON "icon"
+/* MediaItem2 properties */
+#define MS2_PROP_ALBUM "Album"
+#define MS2_PROP_ARTIST "Artist"
+#define MS2_PROP_BITRATE "Bitrate"
+#define MS2_PROP_DURATION "Duration"
+#define MS2_PROP_GENRE "Genre"
+#define MS2_PROP_HEIGHT "Height"
+#define MS2_PROP_MIME_TYPE "MIMEType"
+#define MS2_PROP_TYPE "Type"
+#define MS2_PROP_URLS "URLs"
+#define MS2_PROP_WIDTH "Width"
-/* Item properties */
-#define MS2_PROP_URLS "URLs"
-#define MS2_PROP_MIME_TYPE "mime-type"
-#define MS2_PROP_SIZE "size"
-#define MS2_PROP_ARTIST "artist"
-#define MS2_PROP_ALBUM "album"
-#define MS2_PROP_DATE "date"
-#define MS2_PROP_DLNA_PROFILE "dlna-profile"
-
-/* Audio/Video items properties */
-#define MS2_PROP_DURATION "duration"
-#define MS2_PROP_BITRATE "bitrate"
+/* Other undefined properties; pending to add to spec */
+#define MS2_PROP_CHILD_COUNT "child-count"
+#define MS2_PROP_ICON "icon"
+#define MS2_PROP_SIZE "size"
+#define MS2_PROP_DATE "date"
+#define MS2_PROP_DLNA_PROFILE "dlna-profile"
#define MS2_PROP_SAMPLE_RATE "sample-rate"
#define MS2_PROP_BITS_PER_SAMPLE "bits-per-sample"
-
-/* Video/Image items properties */
-#define MS2_PROP_WIDTH "width"
-#define MS2_PROP_HEIGHT "height"
-#define MS2_PROP_COLOR_DEPTH "color-depth"
-#define MS2_PROP_PIXEL_WIDTH "pixel-width"
-#define MS2_PROP_PIXEL_HEIGHT "pixel-height"
-#define MS2_PROP_THUMBNAIL "thumbnail"
-
-/* Audio items properties */
-#define MS2_PROP_GENRE "genre"
+#define MS2_PROP_COLOR_DEPTH "color-depth"
+#define MS2_PROP_PIXEL_WIDTH "pixel-width"
+#define MS2_PROP_PIXEL_HEIGHT "pixel-height"
+#define MS2_PROP_THUMBNAIL "thumbnail"
/* Type items */
#define MS2_TYPE_CONTAINER "container"
@@ -76,7 +70,7 @@
#define MS2_UNKNOWN_STR ""
/* Root category */
-#define MS2_ROOT "0"
+#define MS2_ROOT ""
typedef enum {
MS2_ERROR_GENERAL = 1
diff --git a/lib/media-server2-server.c b/lib/media-server2-server.c
index 9490ff4..a607182 100644
--- a/lib/media-server2-server.c
+++ b/lib/media-server2-server.c
@@ -25,6 +25,7 @@
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus.h>
#include <string.h>
+#include <stdlib.h>
#include "media-server2-private.h"
#include "media-server2-server.h"
@@ -58,6 +59,24 @@ struct _MS2ServerPrivate {
};
static const gchar introspect_sgn[] = { DBUS_TYPE_INVALID };
+static const gchar get_sgn[] = { DBUS_TYPE_STRING, DBUS_TYPE_STRING, DBUS_TYPE_INVALID };
+
+static const gchar *mediaobject2_properties[] = { MS2_PROP_DISPLAY_NAME,
+ MS2_PROP_PARENT,
+ MS2_PROP_ID,
+ NULL };
+
+static const gchar *mediaitem2_properties[] = { MS2_PROP_ALBUM,
+ MS2_PROP_ARTIST,
+ MS2_PROP_BITRATE,
+ MS2_PROP_DURATION,
+ MS2_PROP_GENRE,
+ MS2_PROP_HEIGHT,
+ MS2_PROP_MIME_TYPE,
+ MS2_PROP_TYPE,
+ MS2_PROP_URLS,
+ MS2_PROP_WIDTH,
+ NULL };
static guint32 signals[LAST_SIGNAL] = { 0 };
@@ -249,6 +268,167 @@ get_introspection ()
return introspection;
}
+static gboolean
+is_property_valid (const gchar *interface,
+ const gchar *property)
+{
+ const gchar *prop_intern;
+ gboolean found;
+ int i;
+ static gchar **mo2_properties_intern = NULL;
+ static gchar **mi2_properties_intern = NULL;
+
+ /* Initialize MediaObject2 properties interns */
+ if (!mo2_properties_intern) {
+ mo2_properties_intern = g_new (gchar *,
+ g_strv_length ((gchar **) mediaobject2_properties) + 1);
+ for (i = 0; mediaobject2_properties[i]; i++) {
+ mo2_properties_intern[i] =
+ (gchar *) g_intern_static_string (mediaobject2_properties[i]);
+ }
+ mo2_properties_intern[i] = NULL;
+ }
+
+ /* Initialize MediaItem2 properties interns */
+ if (!mi2_properties_intern) {
+ mi2_properties_intern = g_new (gchar *,
+ g_strv_length ((gchar **) mediaitem2_properties) + 1);
+ for (i = 0; mediaitem2_properties[i]; i++) {
+ mi2_properties_intern[i] =
+ (gchar *) g_intern_static_string (mediaitem2_properties[i]);
+ }
+ mi2_properties_intern[i] = NULL;
+ }
+
+ prop_intern = g_intern_string (property);
+
+ /* Check MediaObject2 interface */
+ if (!interface || g_strcmp0 (interface, "org.gnome.UPnP.MediaObject2") == 0) {
+ found = FALSE;
+ i = 0;
+ while (!found && mo2_properties_intern[i]) {
+ found = (prop_intern == mo2_properties_intern[i]);
+ i++;
+ }
+
+ if (found) {
+ return TRUE;
+ }
+
+ /* If not found, but interface is NULL, maybe property is in next interface */
+ if (!found && interface) {
+ return FALSE;
+ }
+ }
+
+ /* Check MediaItem2 interface */
+ if (!interface || g_strcmp0 (interface, "org.gnome.UPnP.MediaItem2") == 0) {
+ found = FALSE;
+ i = 0;
+ while (!found && mi2_properties_intern[i]) {
+ found = (prop_intern == mi2_properties_intern[i]);
+ i++;
+ }
+
+ return found;
+ }
+
+ return FALSE;
+}
+
+static GValue *
+get_property_value (MS2Server *server,
+ const gchar *id,
+ const gchar *interface,
+ const gchar *property)
+{
+ GHashTable *propresult;
+ GValue *propvalue;
+ GValue *v;
+ const gchar *prop[2] = { NULL };
+
+ /* Check everything is right */
+ if (!id ||
+ !property ||
+ !is_property_valid (interface, property) ||
+ !server->priv->get_properties) {
+ return NULL;
+ }
+
+ prop[0] = property;
+ propresult = server->priv->get_properties (id,
+ prop,
+ server->priv->data,
+ NULL);
+ if (!propresult) {
+ return NULL;
+ }
+
+ propvalue = g_hash_table_lookup (propresult, property);
+
+ if (propvalue) {
+ /* Make a copy */
+ v = g_new0 (GValue, 1);
+ g_value_init (v, G_VALUE_TYPE (propvalue));
+ g_value_copy (propvalue, v);
+ }
+
+ g_hash_table_unref (propresult);
+
+ return v;
+}
+
+static gchar *
+get_id (DBusMessage *m)
+{
+ gchar **path;
+ gchar *id;
+ gint path_length;
+
+ dbus_message_get_path_decomposed (m, &path);
+
+ /* Path can of type:
+ /org/gnome/UPnP/MediaServer2/<name>
+ /org/gnome/UPnP/MediaServer2/<name>/items/<id>
+ /org/gnome/UPnP/MediaServer2/<name>/containers/<id>
+ */
+ path_length = g_strv_length (path);
+
+ if (path_length == 5) {
+ id = g_strdup (MS2_ROOT);
+ } else if (path_length == 7) {
+ id = g_strdup (g_quark_to_string (atoi (path[6])));
+ } else {
+ id = NULL;
+ }
+
+ dbus_free_string_array (path);
+
+ return id;
+}
+
+static void
+append_variant_arg (DBusMessage *m, const GValue *v)
+{
+ DBusMessageIter iter;
+ DBusMessageIter sub;
+ const gchar *str_value;
+ gint int_value;
+
+ dbus_message_iter_init_append (m, &iter);
+ if (G_VALUE_HOLDS_STRING (v)) {
+ str_value = g_value_get_string (v);
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "s", &sub);
+ dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, &str_value);
+ dbus_message_iter_close_container (&iter, &sub);
+ } else if (G_VALUE_HOLDS_INT (v)) {
+ int_value = g_value_get_int (v);
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "i", &sub);
+ dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &int_value);
+ dbus_message_iter_close_container (&iter, &sub);
+ }
+}
+
static DBusHandlerResult
handle_introspect_message (DBusConnection *c,
DBusMessage *m,
@@ -271,6 +451,44 @@ handle_introspect_message (DBusConnection *c,
}
static DBusHandlerResult
+handle_get_message (DBusConnection *c,
+ DBusMessage *m,
+ void *userdata)
+{
+ GValue *value;
+ DBusMessage *r;
+ gchar *interface = NULL;
+ gchar *property = NULL;
+ gchar *id;
+ MS2Server *server = MS2_SERVER (userdata);
+
+ /* Check signature */
+ if (dbus_message_has_signature (m, get_sgn)) {
+ dbus_message_get_args (m, NULL,
+ DBUS_TYPE_STRING, &interface,
+ DBUS_TYPE_STRING, &property,
+ DBUS_TYPE_INVALID);
+ id = get_id (m);
+ value = get_property_value (server, id, interface, property);
+ g_free (id);
+ if (!value) {
+ g_printerr ("Invalid property %s in interface %s\n",
+ property,
+ interface);
+ } else {
+ r = dbus_message_new_method_return (m);
+ append_variant_arg (r, value);
+ dbus_connection_send (c, r, NULL);
+ dbus_message_unref (r);
+ free_value (value);
+ }
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+}
+
+static DBusHandlerResult
root_handler (DBusConnection *c,
DBusMessage *m,
void *userdata)
@@ -279,8 +497,14 @@ root_handler (DBusConnection *c,
iface = dbus_message_get_interface (m);
- if (dbus_message_is_method_call (m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+ if (dbus_message_is_method_call (m,
+ "org.freedesktop.DBus.Introspectable",
+ "Introspect")) {
return handle_introspect_message (c, m, userdata);
+ } else if (dbus_message_is_method_call (m,
+ "org.freedesktop.DBus.Properties",
+ "Get")) {
+ return handle_get_message (c, m, userdata);
} else {
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]