X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fproxy.c;h=e1bc420a92698c97197f3295f690247bc9d04bcd;hb=e5cb500cd0a676f693b1503ac59eae08fe0c05c2;hp=f31e9f8e9817bc0dae13757143af9ed02874fd78;hpb=878230b88c24c5f22f1f1fa83f48db98723ff859;p=platform%2Fupstream%2Fconnman.git diff --git a/src/proxy.c b/src/proxy.c old mode 100644 new mode 100755 index f31e9f8..e1bc420 --- a/src/proxy.c +++ b/src/proxy.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2007-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2007-2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -30,70 +30,161 @@ static unsigned int next_lookup_token = 1; static GSList *driver_list = NULL; +static GSList *lookup_list = NULL; struct proxy_lookup { unsigned int token; connman_proxy_lookup_cb cb; void *user_data; + struct connman_service *service; + char *url; guint watch; + struct connman_proxy_driver *proxy; }; +static void remove_lookup(struct proxy_lookup *lookup) +{ + if (lookup->watch > 0) + g_source_remove(lookup->watch); + + lookup_list = g_slist_remove(lookup_list, lookup); + + connman_service_unref(lookup->service); + g_free(lookup->url); + g_free(lookup); +} + +static void remove_lookups(GSList *lookups) +{ + GSList *list; + + for (list = lookups; list; list = list->next) { + struct proxy_lookup *lookup = list->data; + + remove_lookup(lookup); + } + + g_slist_free(lookups); +} + static gboolean lookup_callback(gpointer user_data) { struct proxy_lookup *lookup = user_data; + GSList *list; + + if (!lookup) + return FALSE; lookup->watch = 0; - if (lookup->cb) - lookup->cb(NULL, lookup->user_data); + for (list = driver_list; list; list = list->next) { + struct connman_proxy_driver *proxy = list->data; - g_free(lookup); + if (!proxy->request_lookup) + continue; + + lookup->proxy = proxy; + break; + } + + if (!lookup->proxy || + lookup->proxy->request_lookup(lookup->service, + lookup->url) < 0) { + + if (lookup->cb) + lookup->cb(NULL, lookup->user_data); + + remove_lookup(lookup); + } return FALSE; } unsigned int connman_proxy_lookup(const char *interface, const char *url, - connman_proxy_lookup_cb cb, void *user_data) + struct connman_service *service, + connman_proxy_lookup_cb cb, + void *user_data) { struct proxy_lookup *lookup; DBG("interface %s url %s", interface, url); - if (interface == NULL) + if (!interface) return 0; lookup = g_try_new0(struct proxy_lookup, 1); - if (lookup == NULL) + if (!lookup) return 0; lookup->token = next_lookup_token++; lookup->cb = cb; lookup->user_data = user_data; + lookup->url = g_strdup(url); + lookup->service = connman_service_ref(service); - lookup->watch = g_timeout_add_seconds(0, lookup_callback, lookup); + lookup->watch = g_idle_add(lookup_callback, lookup); if (lookup->watch == 0) { + g_free(lookup->url); g_free(lookup); return 0; } DBG("token %u", lookup->token); + lookup_list = g_slist_prepend(lookup_list, lookup); return lookup->token; } void connman_proxy_lookup_cancel(unsigned int token) { + GSList *list; + struct proxy_lookup *lookup = NULL; + DBG("token %u", token); + + for (list = lookup_list; list; list = list->next) { + lookup = list->data; + + if (lookup->token == token) + break; + + lookup = NULL; + } + + if (lookup) { + if (lookup->proxy && + lookup->proxy->cancel_lookup) + lookup->proxy->cancel_lookup(lookup->service, + lookup->url); + + remove_lookup(lookup); + } } void connman_proxy_driver_lookup_notify(struct connman_service *service, - const char *url, const char *result) + const char *url, const char *result) { + GSList *list, *matches = NULL; + DBG("service %p url %s result %s", service, url, result); - if (service == NULL) - return; + for (list = lookup_list; list; list = list->next) { + struct proxy_lookup *lookup = list->data; + + if (service != lookup->service) + continue; + + if (g_strcmp0(lookup->url, url) == 0) { + if (lookup->cb) + lookup->cb(result, lookup->user_data); + + matches = g_slist_prepend(matches, lookup); + } + } + + if (matches) + remove_lookups(matches); } static gint compare_priority(gconstpointer a, gconstpointer b) @@ -130,9 +221,19 @@ int connman_proxy_driver_register(struct connman_proxy_driver *driver) */ void connman_proxy_driver_unregister(struct connman_proxy_driver *driver) { + GSList *list; + DBG("driver %p name %s", driver, driver->name); driver_list = g_slist_remove(driver_list, driver); + + for (list = lookup_list; list; list = list->next) { + struct proxy_lookup *lookup = list->data; + + if (lookup->proxy == driver) + lookup->proxy = NULL; + } + } int __connman_proxy_init(void) @@ -145,4 +246,6 @@ int __connman_proxy_init(void) void __connman_proxy_cleanup(void) { DBG(""); + + remove_lookups(lookup_list); }