Add support to call registered proxy driver and report
proxy to client.
---
include/proxy.h | 4 ++
src/proxy.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 97 insertions(+), 7 deletions(-)
diff --git a/include/proxy.h b/include/proxy.h
index 61117a0..5dd0583 100644
--- a/include/proxy.h
+++ b/include/proxy.h
@@ -43,6 +43,10 @@ void connman_proxy_lookup_cancel(unsigned int token);
void connman_proxy_driver_lookup_notify(struct connman_service *service,
const char *url, const char *result);
+#define CONNMAN_PROXY_PRIORITY_LOW -100
+#define CONNMAN_PROXY_PRIORITY_DEFAULT 0
+#define CONNMAN_PROXY_PRIORITY_HIGH 100
+
struct connman_proxy_driver {
const char *name;
int priority;
diff --git a/src/proxy.c b/src/proxy.c
index f31e9f8..df27908 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -30,24 +30,74 @@
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;
+ 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;
+ unsigned int token = (unsigned int) user_data;
+ struct proxy_lookup *lookup = NULL;
+ GSList *list;
+
+ for (list = lookup_list; list; list = list->next) {
+ lookup = list->data;
+
+ if (lookup->token == token)
+ break;
+ }
+
+ if (lookup == NULL)
+ 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 == NULL)
+ continue;
+
+ lookup->proxy = proxy;
+ break;
+ }
+
+ if (lookup->proxy == NULL ||
+ lookup->proxy->request_lookup(NULL, lookup->url) < 0) {
+
+ if (lookup->cb)
+ lookup->cb(NULL, lookup->user_data);
+
+ remove_lookup(lookup);
+ }
return FALSE;
}
@@ -70,30 +120,66 @@ unsigned int connman_proxy_lookup(const char *interface,
const char *url,
lookup->cb = cb;
lookup->user_data = user_data;
+ lookup->url = g_strdup(url);
- lookup->watch = g_timeout_add_seconds(0, lookup_callback, lookup);
+ lookup->watch = g_timeout_add_seconds(0, lookup_callback,
+ (gpointer) lookup->token);
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->proxy != NULL &&
+ lookup->proxy->cancel_lookup != NULL)
+ lookup->proxy->cancel_lookup(NULL, 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);
- if (service == NULL)
- return;
+ for (list = lookup_list; list; list = list->next) {
+ struct proxy_lookup *lookup = list->data;
+
+ 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)
--
1.7.2.3
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman