[libdmapsharing] Allow two DMAP sub-protocols (e.g., DAAP and DPAP) in one process
- From: W. Michael Petullo <wmpetullo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdmapsharing] Allow two DMAP sub-protocols (e.g., DAAP and DPAP) in one process
- Date: Thu, 9 Sep 2010 18:53:14 +0000 (UTC)
commit 7071bbd5ea813f0a74b40193fc8ff2953491f5aa
Author: W. Michael Petullo <mike flyn org>
Date: Thu Sep 9 13:57:00 2010 -0500
Allow two DMAP sub-protocols (e.g., DAAP and DPAP) in one process
DmapMdnsPublisher is now a singleton class that stores a running list
of services. This ensures that one DMAP sub-protocol does not unpublish
another when avahi_entry_group_reset() is called.
Signed-off-by: W. Michael Petullo <mike flyn org>
ChangeLog | 5 +
TODO | 3 -
libdmapsharing/dmap-mdns-publisher-avahi.c | 301 ++++++++++++----------------
libdmapsharing/dmap-mdns-publisher.h | 12 +-
libdmapsharing/dmap-share.c | 19 +-
5 files changed, 147 insertions(+), 193 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 95ef0c4..2a11e31 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+09 September 2010 W. Michael Petullo <mike flyn org>
+
+ * Allow two sub-DMAP protocols (e.g., DAAP and DPAP) in one
+ process.
+
07 September 2010 W. Michael Petullo <mike flyn org>
* Allow dmap-mdns-*-dnssd.c to compile.
diff --git a/TODO b/TODO
index 3c0258a..30a9013 100644
--- a/TODO
+++ b/TODO
@@ -1,8 +1,5 @@
Complete DACP code and push Rhythmbox patch
-Allow both DPAP and DAAP sharing in one process (using two threads
-instead of two processes).
-
Reduce the memory usage while building response to media list query.
Replace dmap-md5.[ch] with GChecksum.
diff --git a/libdmapsharing/dmap-mdns-publisher-avahi.c b/libdmapsharing/dmap-mdns-publisher-avahi.c
index 7f690e6..6ebca53 100644
--- a/libdmapsharing/dmap-mdns-publisher-avahi.c
+++ b/libdmapsharing/dmap-mdns-publisher-avahi.c
@@ -46,11 +46,8 @@ static void dmap_mdns_publisher_finalize (GObject *object);
#define DMAP_MDNS_PUBLISHER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DMAP_MDNS_PUBLISHER, DmapMdnsPublisherPrivate))
-struct DmapMdnsPublisherPrivate
+struct DmapMdnsPublisherService
{
- AvahiClient *client;
- AvahiEntryGroup *entry_group;
-
char *name;
guint port;
char *type_of_service;
@@ -58,6 +55,13 @@ struct DmapMdnsPublisherPrivate
gchar **txt_records;
};
+struct DmapMdnsPublisherPrivate
+{
+ AvahiClient *client;
+ AvahiEntryGroup *entry_group;
+ GSList *service;
+};
+
enum {
PUBLISHED,
NAME_COLLISION,
@@ -85,56 +89,38 @@ dmap_mdns_publisher_error_quark (void)
}
static void
+emit_published (char *name, DmapMdnsPublisher *publisher)
+{
+ g_signal_emit (publisher, signals [PUBLISHED], 0, name);
+}
+
+static void
entry_group_cb (AvahiEntryGroup *group,
AvahiEntryGroupState state,
DmapMdnsPublisher *publisher)
{
if (state == AVAHI_ENTRY_GROUP_ESTABLISHED) {
-
- g_signal_emit (publisher, signals [PUBLISHED], 0, publisher->priv->name);
-
+ g_slist_foreach (publisher->priv->service, (GFunc) emit_published, publisher);
} else if (state == AVAHI_ENTRY_GROUP_COLLISION) {
g_warning ("MDNS name collision");
+ /* FIXME: how to know which name collided?
g_signal_emit (publisher, signals [NAME_COLLISION], 0, publisher->priv->name);
+ */
+ g_signal_emit (publisher, signals [NAME_COLLISION], 0, "unknown");
}
}
static gboolean
-create_service (DmapMdnsPublisher *publisher,
- GError **error)
+create_service (struct DmapMdnsPublisherService *service,
+ DmapMdnsPublisher *publisher,
+ GError **error)
{
- int ret;
+ int ret;
const char *password_record;
AvahiStringList *txt_records;
- if (publisher->priv->entry_group == NULL) {
- publisher->priv->entry_group = avahi_entry_group_new (publisher->priv->client,
- (AvahiEntryGroupCallback)entry_group_cb,
- publisher);
- dmap_mdns_avahi_set_entry_group (publisher->priv->entry_group);
- } else {
- avahi_entry_group_reset (publisher->priv->entry_group);
- }
-
- if (publisher->priv->entry_group == NULL) {
- g_warning ("Could not create AvahiEntryGroup for publishing");
- g_set_error (error,
- DMAP_MDNS_PUBLISHER_ERROR,
- DMAP_MDNS_PUBLISHER_ERROR_FAILED,
- "%s",
- _("Could not create AvahiEntryGroup for publishing"));
- return FALSE;
- }
-
-#if 0
- g_message ("Service name:%s port:%u password:%d",
- publisher->priv->name,
- publisher->priv->port,
- publisher->priv->password_required);
-#endif
-
- if (publisher->priv->password_required) {
+ if (service->password_required) {
password_record = "Password=true";
} else {
password_record = "Password=false";
@@ -142,9 +128,9 @@ create_service (DmapMdnsPublisher *publisher,
txt_records = avahi_string_list_new(password_record, NULL);
- if (publisher->priv->txt_records) {
- //g_debug("Number of txt records: %d", publisher->priv->txt_records);
- gchar **txt_record = publisher->priv->txt_records;
+ if (service->txt_records) {
+ //g_debug("Number of txt records: %d", service->txt_records);
+ gchar **txt_record = service->txt_records;
while (*txt_record) {
txt_records = avahi_string_list_add(txt_records, *txt_record);
txt_record++;
@@ -155,11 +141,11 @@ create_service (DmapMdnsPublisher *publisher,
AVAHI_IF_UNSPEC,
AVAHI_PROTO_UNSPEC,
0,
- publisher->priv->name,
- publisher->priv->type_of_service,
+ service->name,
+ service->type_of_service,
NULL,
NULL,
- publisher->priv->port,
+ service->port,
txt_records);
avahi_string_list_free(txt_records);
@@ -174,155 +160,92 @@ create_service (DmapMdnsPublisher *publisher,
return FALSE;
}
- ret = avahi_entry_group_commit (publisher->priv->entry_group);
-
- if (ret < 0) {
- g_set_error (error,
- DMAP_MDNS_PUBLISHER_ERROR,
- DMAP_MDNS_PUBLISHER_ERROR_FAILED,
- "%s: %s",
- _("Could not commit service"),
- avahi_strerror (ret));
- return FALSE;
- }
-
return TRUE;
}
static gboolean
-refresh_service (DmapMdnsPublisher *publisher,
+create_services (DmapMdnsPublisher *publisher,
GError **error)
{
- return create_service (publisher, error);
-}
-
-static gboolean
-publisher_set_name_internal (DmapMdnsPublisher *publisher,
- const char *name,
- GError **error)
-{
- g_free (publisher->priv->name);
- publisher->priv->name = g_strdup (name);
-
- return TRUE;
-}
-
-gboolean
-dmap_mdns_publisher_set_name (DmapMdnsPublisher *publisher,
- const char *name,
- GError **error)
-{
- g_return_val_if_fail (publisher != NULL, FALSE);
-
- publisher_set_name_internal (publisher, name, error);
+ GSList *ptr;
+ int ret;
- if (publisher->priv->entry_group) {
- refresh_service (publisher, error);
+ if (publisher->priv->entry_group == NULL) {
+ publisher->priv->entry_group = avahi_entry_group_new (publisher->priv->client,
+ (AvahiEntryGroupCallback)entry_group_cb,
+ publisher);
+ dmap_mdns_avahi_set_entry_group (publisher->priv->entry_group);
+ } else {
+ avahi_entry_group_reset (publisher->priv->entry_group);
}
- return TRUE;
-}
-
-static gboolean
-publisher_set_port_internal (DmapMdnsPublisher *publisher,
- guint port,
- GError **error)
-{
- publisher->priv->port = port;
-
- return TRUE;
-}
-
-gboolean
-dmap_mdns_publisher_set_port (DmapMdnsPublisher *publisher,
- guint port,
- GError **error)
-{
- g_return_val_if_fail (publisher != NULL, FALSE);
-
- publisher_set_port_internal (publisher, port, error);
-
- if (publisher->priv->entry_group) {
- refresh_service (publisher, error);
+ if (publisher->priv->entry_group == NULL) {
+ g_warning ("Could not create AvahiEntryGroup for publishing");
+ g_set_error (error,
+ DMAP_MDNS_PUBLISHER_ERROR,
+ DMAP_MDNS_PUBLISHER_ERROR_FAILED,
+ "%s",
+ _("Could not create AvahiEntryGroup for publishing"));
+ return FALSE;
}
- return TRUE;
-}
-
-static gboolean
-publisher_set_type_of_service_internal (DmapMdnsPublisher *publisher,
- const char *type_of_service,
- GError **error)
-{
- g_free (publisher->priv->type_of_service);
- publisher->priv->type_of_service = g_strdup (type_of_service);
-
- return TRUE;
-}
-
-gboolean
-dmap_mdns_publisher_set_type_of_service (DmapMdnsPublisher *publisher,
- const char *type_of_service,
- GError **error)
-{
- g_return_val_if_fail (publisher != NULL, FALSE);
+ for (ptr = publisher->priv->service; ptr; ptr = g_slist_next (ptr)) {
+ if (! create_service (ptr->data, publisher, error)) {
+ return FALSE;
+ }
+ }
- publisher_set_type_of_service_internal (publisher, type_of_service, error);
+ ret = avahi_entry_group_commit (publisher->priv->entry_group);
- if (publisher->priv->entry_group) {
- refresh_service (publisher, error);
+ if (ret < 0) {
+ g_set_error (error,
+ DMAP_MDNS_PUBLISHER_ERROR,
+ DMAP_MDNS_PUBLISHER_ERROR_FAILED,
+ "%s: %s",
+ _("Could not commit service"),
+ avahi_strerror (ret));
+ return FALSE;
}
return TRUE;
}
static gboolean
-publisher_set_password_required_internal (DmapMdnsPublisher *publisher,
- gboolean required,
- GError **error)
+refresh_services (DmapMdnsPublisher *publisher,
+ GError **error)
{
- publisher->priv->password_required = required;
- return TRUE;
+ return create_services (publisher, error);
}
gboolean
-dmap_mdns_publisher_set_password_required (DmapMdnsPublisher *publisher,
- gboolean required,
- GError **error)
+dmap_mdns_publisher_rename_at_port (DmapMdnsPublisher *publisher,
+ guint port,
+ const char *name,
+ GError **error)
{
- g_return_val_if_fail (publisher != NULL, FALSE);
+ GSList *ptr;
- publisher_set_password_required_internal (publisher, required, error);
+ g_return_val_if_fail (publisher != NULL, FALSE);
- if (publisher->priv->entry_group) {
- refresh_service (publisher, error);
+ for (ptr = publisher->priv->service; ptr; ptr = g_slist_next (ptr)) {
+ if (port == ((struct DmapMdnsPublisherService *) ptr->data)->port)
+ break;
}
- return TRUE;
-}
-
-
-static gboolean
-publisher_set_txt_records_internal (DmapMdnsPublisher *publisher,
- gchar **txt_records,
- GError **error)
-{
- g_strfreev (publisher->priv->txt_records);
- publisher->priv->txt_records = g_strdupv (txt_records);
- return TRUE;
-}
-
-gboolean
-dmap_mdns_publisher_set_txt_records (DmapMdnsPublisher *publisher,
- gchar **txt_records,
- GError **error)
-{
- g_return_val_if_fail (publisher != NULL, FALSE);
+ if (ptr == NULL) {
+ g_set_error (error,
+ DMAP_MDNS_PUBLISHER_ERROR,
+ DMAP_MDNS_PUBLISHER_ERROR_FAILED,
+ "%s",
+ _("No service at port"));
+ return FALSE;
+ }
- publisher_set_txt_records_internal (publisher, txt_records, error);
+ g_free (((struct DmapMdnsPublisherService *) ptr->data)->name);
+ ((struct DmapMdnsPublisherService *) ptr->data)->name = g_strdup (name);
if (publisher->priv->entry_group) {
- refresh_service (publisher, error);
+ refresh_services (publisher, error);
}
return TRUE;
@@ -337,6 +260,8 @@ dmap_mdns_publisher_publish (DmapMdnsPublisher *publisher,
gchar **txt_records,
GError **error)
{
+ struct DmapMdnsPublisherService *service;
+
if (publisher->priv->client == NULL) {
g_set_error (error,
DMAP_MDNS_PUBLISHER_ERROR,
@@ -346,13 +271,18 @@ dmap_mdns_publisher_publish (DmapMdnsPublisher *publisher,
return FALSE;
}
- publisher_set_name_internal (publisher, name, NULL);
- publisher_set_port_internal (publisher, port, NULL);
- publisher_set_type_of_service_internal (publisher, type_of_service, NULL);
- publisher_set_password_required_internal (publisher, password_required, NULL);
- publisher_set_txt_records_internal (publisher, txt_records, NULL);
+
+ service = g_new (struct DmapMdnsPublisherService, 1);
+
+ service->name = g_strdup(name);
+ service->port = port;
+ service->type_of_service = g_strdup (type_of_service);
+ service->password_required = password_required;
+ service->txt_records = g_strdupv (txt_records);
+
+ publisher->priv->service = g_slist_append (publisher->priv->service, service);
- return create_service (publisher, error);
+ return create_services (publisher, error);
}
gboolean
@@ -410,11 +340,30 @@ dmap_mdns_publisher_get_property (GObject *object,
}
}
+static GObject *
+dmap_mdns_publisher_constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ /* This class is a singleton. */
+ static GObject *self = NULL;
+
+ if (self == NULL) {
+ self = G_OBJECT_CLASS (dmap_mdns_publisher_parent_class)->constructor (
+ type, n_construct_params, construct_params);
+ g_object_add_weak_pointer (self, (gpointer) &self);
+ return self;
+ }
+
+ return g_object_ref (self);
+}
+
static void
dmap_mdns_publisher_class_init (DmapMdnsPublisherClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->constructor = dmap_mdns_publisher_constructor;
object_class->finalize = dmap_mdns_publisher_finalize;
object_class->get_property = dmap_mdns_publisher_get_property;
object_class->set_property = dmap_mdns_publisher_set_property;
@@ -448,7 +397,17 @@ dmap_mdns_publisher_init (DmapMdnsPublisher *publisher)
{
publisher->priv = DMAP_MDNS_PUBLISHER_GET_PRIVATE (publisher);
- publisher->priv->client = dmap_mdns_avahi_get_client ();
+ publisher->priv->client = dmap_mdns_avahi_get_client ();
+ publisher->priv->entry_group = NULL;
+ publisher->priv->service = NULL;
+}
+
+static void
+free_service (struct DmapMdnsPublisherService *service, gpointer user_data)
+{
+ g_free (service->name);
+ g_free (service->type_of_service);
+ g_strfreev (service->txt_records);
}
static void
@@ -470,10 +429,8 @@ dmap_mdns_publisher_finalize (GObject *object)
avahi_client_free (publisher->priv->client);
- g_free (publisher->priv->name);
- g_free (publisher->priv->type_of_service);
-
- g_strfreev (publisher->priv->txt_records);
+ g_slist_foreach (publisher->priv->service, (GFunc) free_service, NULL);
+ g_slist_free (publisher->priv->service);
G_OBJECT_CLASS (dmap_mdns_publisher_parent_class)->finalize (object);
}
diff --git a/libdmapsharing/dmap-mdns-publisher.h b/libdmapsharing/dmap-mdns-publisher.h
index ba5976a..25c3bb1 100644
--- a/libdmapsharing/dmap-mdns-publisher.h
+++ b/libdmapsharing/dmap-mdns-publisher.h
@@ -77,18 +77,10 @@ gboolean dmap_mdns_publisher_publish (DmapMdnsPublish
gboolean password_required,
gchar **txt_records,
GError **error);
-gboolean dmap_mdns_publisher_set_name (DmapMdnsPublisher *publisher,
+gboolean dmap_mdns_publisher_rename_at_port (DmapMdnsPublisher *publisher,
+ guint port,
const char *name,
GError **error);
-gboolean dmap_mdns_publisher_set_port (DmapMdnsPublisher *publisher,
- guint port,
- GError **error);
-gboolean dmap_mdns_publisher_set_password_required (DmapMdnsPublisher *publisher,
- gboolean required,
- GError **error);
-gboolean dmap_mdns_publisher_set_txt_records (DmapMdnsPublisher *publisher,
- gchar **txt_records,
- GError **error);
gboolean dmap_mdns_publisher_withdraw (DmapMdnsPublisher *publisher,
GError **error);
diff --git a/libdmapsharing/dmap-share.c b/libdmapsharing/dmap-share.c
index 166d8df..db0da5b 100644
--- a/libdmapsharing/dmap-share.c
+++ b/libdmapsharing/dmap-share.c
@@ -405,14 +405,17 @@ _dmap_share_set_name (DMAPShare *share, const char *name)
g_free (share->priv->name);
share->priv->name = g_strdup (name);
- error = NULL;
- res = dmap_mdns_publisher_set_name (share->priv->publisher,
- name,
- &error);
- if (error != NULL) {
- g_warning ("Unable to change MDNS service name: %s",
- error->message);
- g_error_free (error);
+ if (share->priv->published) {
+ error = NULL;
+ res = dmap_mdns_publisher_rename_at_port (share->priv->publisher,
+ share->priv->port,
+ name,
+ &error);
+ if (error != NULL) {
+ g_warning ("Unable to change MDNS service name: %s",
+ error->message);
+ g_error_free (error);
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]