diff options
author | Regis Merlino <regis.merlino@intel.com> | 2013-09-02 15:21:17 +0200 |
---|---|---|
committer | Mark Ryan <mark.d.ryan@intel.com> | 2013-09-06 12:17:40 +0200 |
commit | 4d959b08882574b605b8dce48a1fb4d9bf2f7cee (patch) | |
tree | d3c0388d03926c1f114d6b1815beaa78e41e6187 /libdleyna | |
parent | 8c460ff2e476eeb2b7e35471e97308652a0197f2 (diff) | |
download | dleyna-server-4d959b08882574b605b8dce48a1fb4d9bf2f7cee.tar.gz |
[Device] Deprecate LastChange in favor of Changed signal
Fix issue #109
* Remove LastChange signal
* Add Changed signal
* A Changed signal is emitted along with a ContainerUpdateID
signal when LastChange is not managed by the DLNA server.
Signed-off-by: Regis Merlino <regis.merlino@intel.com>
Diffstat (limited to 'libdleyna')
-rw-r--r-- | libdleyna/server/device.c | 154 | ||||
-rw-r--r-- | libdleyna/server/device.h | 1 | ||||
-rw-r--r-- | libdleyna/server/interface.h | 9 | ||||
-rw-r--r-- | libdleyna/server/server.c | 5 |
4 files changed, 153 insertions, 16 deletions
diff --git a/libdleyna/server/device.c b/libdleyna/server/device.c index 4864f43..612a85d 100644 --- a/libdleyna/server/device.c +++ b/libdleyna/server/device.c @@ -98,6 +98,15 @@ struct prv_new_device_ct_t_ { GHashTable *property_map; }; +enum prv_changed_event_type_t_ { + PRV_CHANGED_EVENT_ADD = 1, + PRV_CHANGED_EVENT_MOD, + PRV_CHANGED_EVENT_DEL, + PRV_CHANGED_EVENT_DONE, + PRV_CHANGED_EVENT_CONTAINER +}; +typedef enum prv_changed_event_type_t_ prv_changed_event_type_t; + static void prv_get_child_count(dls_async_task_t *cb_data, dls_device_count_cb_t cb, const gchar *id); static void prv_retrieve_child_count_for_list(dls_async_task_t *cb_data); @@ -265,16 +274,19 @@ static void prv_last_change_decode(GUPnPCDSLastChangeEntry *entry, const char *root_path) { GUPnPCDSLastChangeEvent event; - GVariant *state; const char *object_id; const char *parent_id; const char *mclass; const char *media_class; - char *key[] = {"ADD", "DEL", "MOD", "DONE"}; + const char *media_class_ex; char *parent_path; char *path = NULL; gboolean sub_update; guint32 update_id; + GVariantBuilder *dict; + gboolean mod; + + dict = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); object_id = gupnp_cds_last_change_entry_get_object_id(entry); if (!object_id) @@ -295,21 +307,79 @@ static void prv_last_change_decode(GUPnPCDSLastChangeEntry *entry, if (!mclass) goto on_error; - media_class = dls_props_upnp_class_to_media_spec_ex(mclass); + media_class = dls_props_upnp_class_to_media_spec(mclass); if (!media_class) goto on_error; + media_class_ex = dls_props_upnp_class_to_media_spec_ex(mclass); + parent_path = dls_path_from_id(root_path, parent_id); - state = g_variant_new("(oubos)", path, update_id, sub_update, - parent_path, media_class); + + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_CHANGE_TYPE, + g_variant_new_uint32(PRV_CHANGED_EVENT_ADD)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_PATH, + g_variant_new_string(path)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_UPDATE_ID, + g_variant_new_uint32(update_id)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_SUBTREE_UPDATE, + g_variant_new_boolean(sub_update)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_PARENT, + g_variant_new_string(parent_path)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_TYPE, + g_variant_new_string(media_class)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_TYPE_EX, + g_variant_new_string(media_class_ex)); + g_free(parent_path); break; case GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_REMOVED: case GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED: - state = g_variant_new("(oub)", path, update_id, sub_update); + mod = (event == GUPNP_CDS_LAST_CHANGE_EVENT_OBJECT_MODIFIED); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_CHANGE_TYPE, + g_variant_new_uint32(mod ? PRV_CHANGED_EVENT_MOD : + PRV_CHANGED_EVENT_DEL)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_PATH, + g_variant_new_string(path)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_UPDATE_ID, + g_variant_new_uint32(update_id)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_SUBTREE_UPDATE, + g_variant_new_boolean(sub_update)); break; case GUPNP_CDS_LAST_CHANGE_EVENT_ST_DONE: - state = g_variant_new("(ou)", path, update_id); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_CHANGE_TYPE, + g_variant_new_uint32(PRV_CHANGED_EVENT_DONE)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_PATH, + g_variant_new_string(path)); + g_variant_builder_add( + dict, "{sv}", + DLS_INTERFACE_PROP_UPDATE_ID, + g_variant_new_uint32(update_id)); break; case GUPNP_CDS_LAST_CHANGE_EVENT_INVALID: default: @@ -317,10 +387,12 @@ static void prv_last_change_decode(GUPnPCDSLastChangeEntry *entry, break; } - g_variant_builder_add(array, "(sv)", key[event - 1], state); + g_variant_builder_add(array, "@a{sv}", g_variant_builder_end(dict)); + on_error: + g_variant_builder_unref(dict); g_free(path); } @@ -354,7 +426,7 @@ static void prv_last_change_cb(GUPnPServiceProxy *proxy, goto on_error; } - g_variant_builder_init(&array, G_VARIANT_TYPE("a(sv)")); + g_variant_builder_init(&array, G_VARIANT_TYPE("aa{sv}")); next = list; while (next) { prv_last_change_decode(next->data, &array, device->path); @@ -362,12 +434,12 @@ static void prv_last_change_cb(GUPnPServiceProxy *proxy, next = g_list_next(next); } - val = g_variant_new("(@a(sv))", g_variant_builder_end(&array)); + val = g_variant_new("(@aa{sv})", g_variant_builder_end(&array)); (void) dls_server_get_connector()->notify(device->connection, device->path, DLEYNA_SERVER_INTERFACE_MEDIA_DEVICE, - DLS_INTERFACE_ESV_LAST_CHANGE, + DLS_INTERFACE_CHANGED_EVENT, val, NULL); @@ -407,6 +479,44 @@ static void prv_build_container_update_array(const gchar *root_path, g_strfreev(str_array); } +static void prv_build_container_update_changed_array(const gchar *root_path, + const gchar *value, + GVariantBuilder *builder) +{ + gchar **str_array; + int pos = 0; + gchar *path; + guint id; + GVariantBuilder dict; + + str_array = g_strsplit(value, ",", 0); + + while (str_array[pos] && str_array[pos + 1]) { + g_variant_builder_init(&dict, G_VARIANT_TYPE("a{sv}")); + + path = dls_path_from_id(root_path, str_array[pos++]); + id = atoi(str_array[pos++]); + + g_variant_builder_add( + &dict, "{sv}", + DLS_INTERFACE_PROP_CHANGE_TYPE, + g_variant_new_uint32(PRV_CHANGED_EVENT_CONTAINER)); + g_variant_builder_add(&dict, "{sv}", + DLS_INTERFACE_PROP_PATH, + g_variant_new_string(path)); + g_variant_builder_add(&dict, "{sv}", + DLS_INTERFACE_PROP_UPDATE_ID, + g_variant_new_uint32(id)); + + g_variant_builder_add(builder, "@a{sv}", + g_variant_builder_end(&dict)); + + g_free(path); + } + + g_strfreev(str_array); +} + static void prv_container_update_cb(GUPnPServiceProxy *proxy, const char *variable, GValue *value, @@ -429,6 +539,25 @@ static void prv_container_update_cb(GUPnPServiceProxy *proxy, g_variant_new("(@a(ou))", g_variant_builder_end(&array)), NULL); + + if (!device->has_last_change) { + g_variant_builder_init(&array, G_VARIANT_TYPE("aa{sv}")); + + prv_build_container_update_changed_array( + device->path, + g_value_get_string(value), + &array); + + (void) dls_server_get_connector()->notify( + device->connection, + device->path, + DLEYNA_SERVER_INTERFACE_MEDIA_DEVICE, + DLS_INTERFACE_CHANGED_EVENT, + g_variant_new("(@aa{sv})", + g_variant_builder_end( + &array)), + NULL); + } } static void prv_system_update_cb(GUPnPServiceProxy *proxy, @@ -870,6 +999,9 @@ static void prv_get_search_capabilities_cb(GUPnPServiceProxy *proxy, prv_get_capabilities_analyze(priv_t->property_map, result, &priv_t->dev->search_caps); + if (g_hash_table_lookup(priv_t->property_map, "upnp:objectUpdateID")) + priv_t->dev->has_last_change = TRUE; + on_error: if (error) diff --git a/libdleyna/server/device.h b/libdleyna/server/device.h index 530f976..6771464 100644 --- a/libdleyna/server/device.h +++ b/libdleyna/server/device.h @@ -63,6 +63,7 @@ struct dls_device_t_ { GVariant *sort_ext_caps; GVariant *feature_list; gboolean shutting_down; + gboolean has_last_change; guint construct_step; dls_device_icon_t icon; }; diff --git a/libdleyna/server/interface.h b/libdleyna/server/interface.h index 57f6dea..f8cb6c6 100644 --- a/libdleyna/server/interface.h +++ b/libdleyna/server/interface.h @@ -123,6 +123,11 @@ enum dls_interface_type_ { /* Evented State Variable Properties */ #define DLS_INTERFACE_PROP_ESV_SYSTEM_UPDATE_ID "SystemUpdateID" +/* Changed event properties */ +#define DLS_INTERFACE_PROP_CHANGE_TYPE "ChangeType" +#define DLS_INTERFACE_PROP_UPDATE_ID "UpdateID" +#define DLS_INTERFACE_PROP_SUBTREE_UPDATE "SubTreeUpdate" + #define DLS_INTERFACE_GET_VERSION "GetVersion" #define DLS_INTERFACE_GET_SERVERS "GetServers" #define DLS_INTERFACE_RESCAN "Rescan" @@ -180,8 +185,8 @@ enum dls_interface_type_ { #define DLS_INTERFACE_INVALIDATED_PROPERTIES "InvalidatedProperties" #define DLS_INTERFACE_ESV_CONTAINER_UPDATE_IDS "ContainerUpdateIDs" #define DLS_INTERFACE_CONTAINER_PATHS_ID "ContainerPathsIDs" -#define DLS_INTERFACE_ESV_LAST_CHANGE "LastChange" -#define DLS_INTERFACE_LAST_CHANGE_STATE_EVENT "StateEvent" +#define DLS_INTERFACE_CHANGED_EVENT "Changed" +#define DLS_INTERFACE_CHANGED_OBJECTS "ChangedObjects" #define DLS_INTERFACE_DELETE "Delete" diff --git a/libdleyna/server/server.c b/libdleyna/server/server.c index 10e01c0..20c5704 100644 --- a/libdleyna/server/server.c +++ b/libdleyna/server/server.c @@ -513,9 +513,8 @@ static const gchar g_server_introspection[] = " <signal name='"DLS_INTERFACE_ESV_CONTAINER_UPDATE_IDS"'>" " <arg type='a(ou)' name='"DLS_INTERFACE_CONTAINER_PATHS_ID"'/>" " </signal>" - " <signal name='"DLS_INTERFACE_ESV_LAST_CHANGE"'>" - " <arg type='a(sv)' name='" - DLS_INTERFACE_LAST_CHANGE_STATE_EVENT"'/>" + " <signal name='"DLS_INTERFACE_CHANGED_EVENT"'>" + " <arg type='aa{sv}' name='"DLS_INTERFACE_CHANGED_OBJECTS"'/>" " </signal>" " <signal name='"DLS_INTERFACE_UPLOAD_UPDATE"'>" " <arg type='u' name='"DLS_INTERFACE_UPLOAD_ID"'/>" |