/src/proxy.c
https://github.com/connectivity/connman-stable · C · 250 lines · 156 code · 60 blank · 34 comment · 35 complexity · 910d81b40bb30b649ba5503b5e9055df MD5 · raw file
- /*
- *
- * Connection Manager
- *
- * Copyright (C) 2007-2010 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
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <glib.h>
- #include "connman.h"
- 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)
- {
- lookup_list = g_slist_remove(lookup_list, lookup);
- 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 == NULL)
- return FALSE;
- lookup->watch = 0;
- for (list = driver_list; list; list = list->next) {
- struct connman_proxy_driver *proxy = list->data;
- if (proxy->request_lookup == NULL)
- continue;
- lookup->proxy = proxy;
- break;
- }
- if (lookup->proxy == NULL ||
- 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,
- 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)
- return 0;
- lookup = g_try_new0(struct proxy_lookup, 1);
- if (lookup == NULL)
- return 0;
- lookup->token = next_lookup_token++;
- lookup->cb = cb;
- lookup->user_data = user_data;
- lookup->url = g_strdup(url);
- lookup->service = service;
- lookup->watch = g_timeout_add_seconds(0, 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_append(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;
- }
- if (lookup != NULL) {
- if (lookup->watch > 0) {
- g_source_remove(lookup->watch);
- lookup->watch = 0;
- }
- if (lookup->proxy != NULL &&
- lookup->proxy->cancel_lookup != NULL)
- 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)
- {
- GSList *list, *matches = NULL;
- DBG("service %p url %s result %s", service, url, result);
- 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_append(matches, lookup);
- }
- }
- if (matches != NULL)
- remove_lookups(matches);
- }
- static gint compare_priority(gconstpointer a, gconstpointer b)
- {
- const struct connman_proxy_driver *driver1 = a;
- const struct connman_proxy_driver *driver2 = b;
- return driver2->priority - driver1->priority;
- }
- /**
- * connman_proxy_driver_register:
- * @driver: Proxy driver definition
- *
- * Register a new proxy driver
- *
- * Returns: %0 on success
- */
- int connman_proxy_driver_register(struct connman_proxy_driver *driver)
- {
- DBG("driver %p name %s", driver, driver->name);
- driver_list = g_slist_insert_sorted(driver_list, driver,
- compare_priority);
- return 0;
- }
- /**
- * connman_proxy_driver_unregister:
- * @driver: Proxy driver definition
- *
- * Remove a previously registered proxy 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)
- {
- DBG("");
- return 0;
- }
- void __connman_proxy_cleanup(void)
- {
- DBG("");
- remove_lookups(lookup_list);
- }