[gssdp/wip/client-cache: 2/4] Add user-agent cache to GSSDP client



commit 636029b90597ff4d949351cef8365616228312f1
Author: Jens Georg <mail jensge org>
Date:   Fri Dec 30 18:38:28 2011 +0100

    Add user-agent cache to GSSDP client
    
    https://bugzilla.gnome.org/show_bug.cgi?id=653894

 doc/gssdp-sections.txt  |    2 +
 libgssdp/gssdp-client.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++-
 libgssdp/gssdp-client.h |    9 ++++++
 3 files changed, 82 insertions(+), 1 deletions(-)
---
diff --git a/doc/gssdp-sections.txt b/doc/gssdp-sections.txt
index 7b73261..bd4fe41 100644
--- a/doc/gssdp-sections.txt
+++ b/doc/gssdp-sections.txt
@@ -11,6 +11,8 @@ gssdp_client_get_host_ip
 gssdp_client_set_network
 gssdp_client_get_network
 gssdp_client_get_active
+gssdp_client_add_cache_entry
+gssdp_client_guess_user_agent
 <SUBSECTION Standard>
 GSSDP_CLIENT
 GSSDP_IS_CLIENT
diff --git a/libgssdp/gssdp-client.c b/libgssdp/gssdp-client.c
index 1ed086b..0d79d6f 100644
--- a/libgssdp/gssdp-client.c
+++ b/libgssdp/gssdp-client.c
@@ -64,6 +64,7 @@ typedef unsigned long in_addr_t;
 #include "gssdp-socket-source.h"
 #include "gssdp-marshal.h"
 #include "gssdp-protocol.h"
+#include "gssdp-socket-functions.h"
 
 #ifndef INET6_ADDRSTRLEN
 #define INET6_ADDRSTRLEN 46
@@ -95,6 +96,7 @@ struct _GSSDPClientPrivate {
         GSSDPSocketSource *search_socket;
 
         gboolean           active;
+        GHashTable        *user_agent_cache;
 };
 
 enum {
@@ -104,7 +106,7 @@ enum {
         PROP_IFACE,
         PROP_NETWORK,
         PROP_HOST_IP,
-        PROP_ACTIVE
+        PROP_ACTIVE,
 };
 
 enum {
@@ -261,6 +263,11 @@ gssdp_client_initable_init (GInitable     *initable,
         gssdp_socket_source_attach (client->priv->multicast_socket);
         gssdp_socket_source_attach (client->priv->search_socket);
 
+        client->priv->user_agent_cache = g_hash_table_new_full (g_str_hash,
+                                                                g_str_equal,
+                                                                g_free,
+                                                                g_free);
+
         return TRUE;
 }
 
@@ -384,6 +391,8 @@ gssdp_client_finalize (GObject *object)
         g_free (client->priv->iface);
         g_free (client->priv->host_ip);
         g_free (client->priv->network);
+        if (client->priv->user_agent_cache)
+                g_hash_table_unref (client->priv->user_agent_cache);
 
         G_OBJECT_CLASS (gssdp_client_parent_class)->finalize (object);
 }
@@ -707,6 +716,67 @@ gssdp_client_get_active (GSSDPClient *client)
 }
 
 /**
+ * gssdp_client_add_cache_entry:
+ * @client: A #GSSDPClient
+ * @ip_address: The host to add to the cache
+ * @user_agent: User agent ot the host to add
+ **/
+void
+gssdp_client_add_cache_entry (GSSDPClient  *client,
+                               const char   *ip_address,
+                               const char   *user_agent)
+{
+        char *hwaddr;
+
+        g_return_if_fail (client != NULL);
+        g_return_if_fail (ip_address != NULL);
+        g_return_if_fail (user_agent != NULL);
+
+        hwaddr = arp_lookup (client, ip_address);
+
+        if (hwaddr)
+                g_hash_table_insert (client->priv->user_agent_cache,
+                                     hwaddr,
+                                     g_strdup (user_agent));
+}
+
+/**
+ * gssdp_client_guess_user_agent:
+ * @client: A #GSSDPClient
+ * @ip_address: IP address to guess the user-agent for
+ *
+ * Try to guess map the given @ip_address to a previously seen user-agent.
+ * This is to help with devices that don't provide user-agents later on but
+ * might be quirky to handle (like Samsung TVs).
+ *
+ * Returns: (transfer none): The user-agent cached for @ip_address, %NULL if none
+ * is cached.
+ **/
+const char *
+gssdp_client_guess_user_agent (GSSDPClient *client,
+                               const char  *ip_address)
+{
+        char *hwaddr;
+
+        g_return_val_if_fail (GSSDP_IS_CLIENT (client), NULL);
+        g_return_val_if_fail (ip_address != NULL, NULL);
+
+        hwaddr = arp_lookup (client, ip_address);
+
+        if (hwaddr) {
+                const char *agent;
+
+                agent = g_hash_table_lookup (client->priv->user_agent_cache,
+                                             hwaddr);
+                g_free (hwaddr);
+
+                return agent;
+        }
+
+        return NULL;
+}
+
+/**
  * _gssdp_client_send_message:
  * @client: A #GSSDPClient
  * @dest_ip: The destination IP address, or NULL to broadcast
diff --git a/libgssdp/gssdp-client.h b/libgssdp/gssdp-client.h
index 2b564f1..9590f55 100644
--- a/libgssdp/gssdp-client.h
+++ b/libgssdp/gssdp-client.h
@@ -103,6 +103,15 @@ gssdp_client_get_network      (GSSDPClient  *client);
 gboolean
 gssdp_client_get_active       (GSSDPClient  *client);
 
+void
+gssdp_client_add_cache_entry  (GSSDPClient  *client,
+                               const char   *ip_address,
+                               const char   *user_agent);
+
+const char *
+gssdp_client_guess_user_agent (GSSDPClient *client,
+                               const char  *ip_address);
+
 G_END_DECLS
 
 #endif /* __GSSDP_CLIENT_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]