5 * Copyright (C) 2007-2010 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
29 #include <gweb/gweb.h>
33 #define STATUS_URL "http://www.connman.net/online/status.html"
35 struct connman_wispr_portal_context {
36 struct connman_service *service;
37 enum connman_ipconfig_type type;
39 /* Portal/WISPr common */
44 struct connman_wispr_portal {
45 struct connman_wispr_portal_context *ipv4_context;
46 struct connman_wispr_portal_context *ipv6_context;
49 static GHashTable *wispr_portal_list = NULL;
51 static void free_connman_wispr_portal_context(struct connman_wispr_portal_context *wp_context)
55 if (wp_context == NULL)
58 if (wp_context->token > 0)
59 connman_proxy_lookup_cancel(wp_context->token);
61 g_web_unref(wp_context->web);
66 static void free_connman_wispr_portal(gpointer data)
68 struct connman_wispr_portal *wispr_portal = data;
72 if (wispr_portal == NULL)
75 free_connman_wispr_portal_context(wispr_portal->ipv4_context);
76 free_connman_wispr_portal_context(wispr_portal->ipv6_context);
81 static void web_debug(const char *str, void *data)
83 connman_info("%s: %s\n", (const char *) data, str);
86 static void proxy_callback(const char *proxy, void *user_data)
88 struct connman_wispr_portal_context *wp_context = user_data;
90 DBG("proxy %s", proxy);
92 wp_context->token = 0;
95 proxy = getenv("http_proxy");
97 if (getenv("CONNMAN_WEB_DEBUG"))
98 g_web_set_debug(wp_context->web, web_debug, "WEB");
100 if (proxy != NULL && g_strcmp0(proxy, "DIRECT") != 0)
101 g_web_set_proxy(wp_context->web, proxy);
103 g_web_set_accept(wp_context->web, NULL);
104 g_web_set_user_agent(wp_context->web, "ConnMan/%s", VERSION);
105 g_web_set_close_connection(wp_context->web, TRUE);
108 static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
110 enum connman_service_type service_type;
111 char *interface = NULL;
114 DBG("wispr/portal context %p", wp_context);
115 DBG("service %p", wp_context->service);
117 service_type = connman_service_get_type(wp_context->service);
119 switch (service_type) {
120 case CONNMAN_SERVICE_TYPE_ETHERNET:
121 case CONNMAN_SERVICE_TYPE_WIFI:
122 case CONNMAN_SERVICE_TYPE_WIMAX:
123 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
124 case CONNMAN_SERVICE_TYPE_CELLULAR:
126 case CONNMAN_SERVICE_TYPE_UNKNOWN:
127 case CONNMAN_SERVICE_TYPE_SYSTEM:
128 case CONNMAN_SERVICE_TYPE_GPS:
129 case CONNMAN_SERVICE_TYPE_VPN:
130 case CONNMAN_SERVICE_TYPE_GADGET:
134 interface = connman_service_get_interface(wp_context->service);
135 if (interface == NULL)
138 DBG("interface %s", interface);
140 wp_context->web = g_web_new(0);
141 if (wp_context->web == NULL) {
146 if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4)
147 g_web_set_address_family(wp_context->web, AF_INET);
149 g_web_set_address_family(wp_context->web, AF_INET6);
151 wp_context->token = connman_proxy_lookup(interface,
152 STATUS_URL, wp_context->service,
153 proxy_callback, wp_context);
154 if (wp_context->token == 0)
162 int __connman_wispr_start(struct connman_service *service,
163 enum connman_ipconfig_type type)
165 struct connman_wispr_portal_context *wp_context = NULL;
166 struct connman_wispr_portal *wispr_portal = NULL;
169 DBG("service %p", service);
171 if (wispr_portal_list == NULL)
174 index = __connman_service_get_index(service);
178 wispr_portal = g_hash_table_lookup(wispr_portal_list,
179 GINT_TO_POINTER(index));
180 if (wispr_portal == NULL) {
181 wispr_portal = g_try_new0(struct connman_wispr_portal, 1);
182 if (wispr_portal == NULL)
185 g_hash_table_replace(wispr_portal_list,
186 GINT_TO_POINTER(index), wispr_portal);
189 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
190 wp_context = wispr_portal->ipv4_context;
191 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
192 wp_context = wispr_portal->ipv6_context;
196 if (wp_context == NULL) {
197 wp_context = g_try_new0(struct connman_wispr_portal_context, 1);
198 if (wp_context == NULL)
201 wp_context->service = service;
202 wp_context->type = type;
204 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
205 wispr_portal->ipv4_context = wp_context;
207 wispr_portal->ipv6_context = wp_context;
209 return wispr_portal_detect(wp_context);
215 void __connman_wispr_stop(struct connman_service *service)
219 DBG("service %p", service);
221 if (wispr_portal_list == NULL)
224 index = __connman_service_get_index(service);
228 g_hash_table_remove(wispr_portal_list, GINT_TO_POINTER(index));
231 int __connman_wispr_init(void)
235 wispr_portal_list = g_hash_table_new_full(g_direct_hash,
236 g_direct_equal, NULL,
237 free_connman_wispr_portal);
242 void __connman_wispr_cleanup(void)
246 g_hash_table_destroy(wispr_portal_list);
247 wispr_portal_list = NULL;