summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJens Georg <jensg@openismus.com>2012-10-23 15:52:13 +0200
committerJens Georg <jensg@openismus.com>2012-10-29 15:51:26 +0100
commit8844fc7867e1aca5382fd51fb64b506908a50534 (patch)
tree61980a6e74d9254e832c805b20b525d8d8bbc1d2 /src
parentc82024c3ba450787be7875f24b5729a6dbf9176b (diff)
downloadrygel-8844fc7867e1aca5382fd51fb64b506908a50534.tar.gz
server: Implement Service Reset Procedure
Diffstat (limited to 'src')
-rw-r--r--src/librygel-server/rygel-content-directory.vala58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/librygel-server/rygel-content-directory.vala b/src/librygel-server/rygel-content-directory.vala
index 0826c186..9d94d8be 100644
--- a/src/librygel-server/rygel-content-directory.vala
+++ b/src/librygel-server/rygel-content-directory.vala
@@ -408,6 +408,16 @@ internal class Rygel.ContentDirectory: Service {
bool sub_tree_update) {
this.system_update_id++;
this.add_last_change_entry (object, event_type, sub_tree_update);
+ var plugin = this.root_device.resource_factory as MediaServerPlugin;
+
+ if (this.system_update_id == 0 &&
+ PluginCapabilities.TRACK_CHANGES in plugin.capabilities) {
+ // Overflow, need to initiate Service Reset Procedure.
+ // See ContentDirectory:3 spec, 2.3.7.1
+ this.service_reset.begin ();
+
+ return;
+ }
if (event_type == ObjectEventType.ADDED ||
event_type == ObjectEventType.DELETED) {
@@ -577,4 +587,52 @@ internal class Rygel.ContentDirectory: Service {
value.init (typeof (string));
value.set_string (this.service_reset_token);
}
+
+ private async void service_reset () {
+ debug ("SystemUpdateID overflow, initiating service reset procedure");
+
+ var plugin = this.root_device.resource_factory as MediaServerPlugin;
+ plugin.active = false;
+ this.service_reset_token = UUID.get ();
+ var expression = new RelationalExpression ();
+ expression.operand1 = "upnp:objectUpdateID";
+ expression.operand2 = "true";
+ expression.op = SearchCriteriaOp.EXISTS;
+
+ try {
+ var root = this.root_container as SearchableContainer;
+ if (root == null) {
+ // TODO:
+ return;
+ }
+
+ uint32 matches = 0;
+ var objects = yield root.search (expression,
+ 0,
+ 0,
+ out matches,
+ "",
+ null);
+ if (objects.size > 0) {
+ uint32 count = 1;
+ foreach (var object in objects) {
+ object.object_update_id = count++;
+
+ if (object is TrackableContainer) {
+ var container = object as MediaContainer;
+ container.update_id = container.object_update_id;
+ container.total_deleted_child_count = 0;
+ }
+ }
+
+ // SystemUpdateID needs to be the highest object_update_id
+ this.system_update_id = count - 1;
+ debug ("New SystemUpdateID is %u", this.system_update_id);
+ }
+
+ debug ("Service reset procedure done, device coming up again");
+ plugin.active = true;
+ debug ("New service reset token is %s", this.service_reset_token);
+ } catch (Error error) { warning ("Failed to search for objects..."); };
+ }
}