diff options
author | Jens Georg <jensg@openismus.com> | 2012-10-23 15:52:13 +0200 |
---|---|---|
committer | Jens Georg <jensg@openismus.com> | 2012-10-29 15:51:26 +0100 |
commit | 8844fc7867e1aca5382fd51fb64b506908a50534 (patch) | |
tree | 61980a6e74d9254e832c805b20b525d8d8bbc1d2 /src | |
parent | c82024c3ba450787be7875f24b5729a6dbf9176b (diff) | |
download | rygel-8844fc7867e1aca5382fd51fb64b506908a50534.tar.gz |
server: Implement Service Reset Procedure
Diffstat (limited to 'src')
-rw-r--r-- | src/librygel-server/rygel-content-directory.vala | 58 |
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..."); }; + } } |