[rygel] core: Serve special description to Xbox
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] core: Serve special description to Xbox
- Date: Thu, 1 Apr 2010 22:56:05 +0000 (UTC)
commit 2ca6fe1f5b21b8559c9bbc97ceae86dc135f3a5d
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Wed Mar 31 22:22:51 2010 +0300
core: Serve special description to Xbox
src/rygel/rygel-root-device-factory.vala | 16 ++++--
src/rygel/rygel-xbox-hacks.vala | 97 ++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+), 5 deletions(-)
---
diff --git a/src/rygel/rygel-root-device-factory.vala b/src/rygel/rygel-root-device-factory.vala
index 9822798..d676ea6 100644
--- a/src/rygel/rygel-root-device-factory.vala
+++ b/src/rygel/rygel-root-device-factory.vala
@@ -58,11 +58,17 @@ internal class Rygel.RootDeviceFactory {
/* Create the description xml */
var doc = this.create_desc (plugin, desc_path, template_path);
- return new RootDevice (this.context,
- plugin,
- doc,
- desc_path,
- BuildConfig.DATA_DIR);
+ var device = new RootDevice (this.context,
+ plugin,
+ doc,
+ desc_path,
+ BuildConfig.DATA_DIR);
+
+ /* Now apply the Xbox hacks */
+ var xbox_hacks = new XBoxHacks ();
+ xbox_hacks.apply_on_device (device, desc_path);
+
+ return device;
}
private XMLDoc create_desc (Plugin plugin,
diff --git a/src/rygel/rygel-xbox-hacks.vala b/src/rygel/rygel-xbox-hacks.vala
index 4be42cc..10d07c2 100644
--- a/src/rygel/rygel-xbox-hacks.vala
+++ b/src/rygel/rygel-xbox-hacks.vala
@@ -23,12 +23,20 @@
using Soup;
using GUPnP;
+using CStuff;
internal errordomain Rygel.XBoxHacksError {
NA
}
internal class Rygel.XBoxHacks : GLib.Object {
+ private static string AGENT = ".*Xbox.*";
+ private static string DMS = "urn:schemas-upnp-org:device:MediaServer";
+ private static string DMS_V1 = DMS + ":1";
+ private static string FRIENDLY_NAME_POSTFIX =
+ ": 1 : Windows Media Connect";
+ private static string MODEL_NAME = "Windows Media Connect";
+
public XBoxHacks.for_action (ServiceAction action) throws XBoxHacksError {
var agent = action.get_message ().request_headers.get ("User-Agent");
if (!agent.contains ("Xbox")) {
@@ -36,6 +44,23 @@ internal class Rygel.XBoxHacks : GLib.Object {
}
}
+ public void apply_on_device (RootDevice device,
+ string template_path) throws Error {
+ if (!device.get_device_type ().has_prefix (DMS)) {
+ return;
+ }
+
+ var doc = new XMLDoc.from_path (template_path);
+ this.modify_dms_desc (doc.doc);
+
+ var desc_path = template_path.replace (".xml", "-xbox.xml");
+ this.save_modified_desc (doc, desc_path);
+
+ var regex = new Regex (AGENT, RegexCompileFlags.CASELESS, 0);
+ var server_path = "/" + device.get_relative_location ();
+ device.context.host_path_for_agent (desc_path, server_path, regex);
+ }
+
public void translate_container_id (ref string container_id) {
if (container_id == "1" ||
container_id == "4" ||
@@ -54,4 +79,76 @@ internal class Rygel.XBoxHacks : GLib.Object {
item.mime_type = "invalid/content";
}
}
+
+ private void modify_dms_desc (Xml.Doc doc) {
+ var element = Utils.get_xml_element ((Xml.Node *) doc,
+ "root",
+ "device",
+ "deviceType");
+ assert (element != null);
+ element->set_content (DMS_V1);
+
+ element = Utils.get_xml_element ((Xml.Node *) doc,
+ "root",
+ "device",
+ "modelName");
+ assert (element != null);
+ element->set_content (MODEL_NAME);
+
+ element = Utils.get_xml_element ((Xml.Node *) doc,
+ "root",
+ "device",
+ "friendlyName");
+ assert (element != null);
+ element->add_content (FRIENDLY_NAME_POSTFIX);
+
+ element = this.find_cds_type_node (doc);
+ assert (element != null);
+ element->set_content (ContentDirectory.UPNP_TYPE_V1);
+ }
+
+ private Xml.Node * find_cds_type_node (Xml.Node *doc_node) {
+ var element = Utils.get_xml_element (doc_node,
+ "root",
+ "device",
+ "serviceList");
+ assert (element != null && element->children != null);
+
+ Xml.Node *cds_type_node = null;
+
+ for (var service_node = element->children;
+ service_node != null;
+ service_node = service_node->next) {
+ for (var type_node = service_node->children;
+ type_node != null;
+ type_node = type_node->next) {
+ if (type_node->name == "serviceType" &&
+ type_node->get_content () == ContentDirectory.UPNP_TYPE) {
+ cds_type_node = type_node;
+ }
+ }
+
+ if (cds_type_node != null) {
+ break;
+ }
+ }
+
+ return cds_type_node;
+ }
+
+ private void save_modified_desc (XMLDoc doc,
+ string desc_path) throws GLib.Error {
+ FileStream f = FileStream.open (desc_path, "w+");
+ int res = -1;
+
+ if (f != null)
+ res = doc.doc.dump (f);
+
+ if (f == null || res == -1) {
+ string message = "Failed to write modified description" +
+ " to %s.\n".printf (desc_path);
+
+ throw new IOError.FAILED (message);
+ }
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]