5 * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 static unsigned int next_lookup_token = 1;
32 static GSList *driver_list = NULL;
33 static GSList *lookup_list = NULL;
37 connman_proxy_lookup_cb cb;
39 struct connman_service *service;
42 struct connman_proxy_driver *proxy;
45 static void remove_lookup(struct proxy_lookup *lookup)
47 lookup_list = g_slist_remove(lookup_list, lookup);
49 connman_service_unref(lookup->service);
54 static void remove_lookups(GSList *lookups)
58 for (list = lookups; list; list = list->next) {
59 struct proxy_lookup *lookup = list->data;
61 remove_lookup(lookup);
64 g_slist_free(lookups);
67 static gboolean lookup_callback(gpointer user_data)
69 struct proxy_lookup *lookup = user_data;
77 for (list = driver_list; list; list = list->next) {
78 struct connman_proxy_driver *proxy = list->data;
80 if (proxy->request_lookup == NULL)
83 lookup->proxy = proxy;
87 if (lookup->proxy == NULL ||
88 lookup->proxy->request_lookup(lookup->service,
92 lookup->cb(NULL, lookup->user_data);
94 remove_lookup(lookup);
100 unsigned int connman_proxy_lookup(const char *interface, const char *url,
101 struct connman_service *service,
102 connman_proxy_lookup_cb cb,
105 struct proxy_lookup *lookup;
107 DBG("interface %s url %s", interface, url);
109 if (interface == NULL)
112 lookup = g_try_new0(struct proxy_lookup, 1);
116 lookup->token = next_lookup_token++;
119 lookup->user_data = user_data;
120 lookup->url = g_strdup(url);
121 lookup->service = connman_service_ref(service);
123 lookup->watch = g_timeout_add_seconds(0, lookup_callback, lookup);
124 if (lookup->watch == 0) {
130 DBG("token %u", lookup->token);
131 lookup_list = g_slist_prepend(lookup_list, lookup);
133 return lookup->token;
136 void connman_proxy_lookup_cancel(unsigned int token)
139 struct proxy_lookup *lookup = NULL;
141 DBG("token %u", token);
143 for (list = lookup_list; list; list = list->next) {
146 if (lookup->token == token)
152 if (lookup != NULL) {
153 if (lookup->watch > 0) {
154 g_source_remove(lookup->watch);
158 if (lookup->proxy != NULL &&
159 lookup->proxy->cancel_lookup != NULL)
160 lookup->proxy->cancel_lookup(lookup->service,
163 remove_lookup(lookup);
167 void connman_proxy_driver_lookup_notify(struct connman_service *service,
168 const char *url, const char *result)
170 GSList *list, *matches = NULL;
172 DBG("service %p url %s result %s", service, url, result);
174 for (list = lookup_list; list; list = list->next) {
175 struct proxy_lookup *lookup = list->data;
177 if (service != lookup->service)
180 if (g_strcmp0(lookup->url, url) == 0) {
182 lookup->cb(result, lookup->user_data);
184 matches = g_slist_prepend(matches, lookup);
189 remove_lookups(matches);
192 static gint compare_priority(gconstpointer a, gconstpointer b)
194 const struct connman_proxy_driver *driver1 = a;
195 const struct connman_proxy_driver *driver2 = b;
197 return driver2->priority - driver1->priority;
201 * connman_proxy_driver_register:
202 * @driver: Proxy driver definition
204 * Register a new proxy driver
206 * Returns: %0 on success
208 int connman_proxy_driver_register(struct connman_proxy_driver *driver)
210 DBG("driver %p name %s", driver, driver->name);
212 driver_list = g_slist_insert_sorted(driver_list, driver,
219 * connman_proxy_driver_unregister:
220 * @driver: Proxy driver definition
222 * Remove a previously registered proxy driver
224 void connman_proxy_driver_unregister(struct connman_proxy_driver *driver)
228 DBG("driver %p name %s", driver, driver->name);
230 driver_list = g_slist_remove(driver_list, driver);
232 for (list = lookup_list; list; list = list->next) {
233 struct proxy_lookup *lookup = list->data;
235 if (lookup->proxy == driver)
236 lookup->proxy = NULL;
241 int __connman_proxy_init(void)
248 void __connman_proxy_cleanup(void)
252 remove_lookups(lookup_list);