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
31 #define CONNMAN_API_SUBJECT_TO_CHANGE
32 #include <connman/plugin.h>
33 #include <connman/location.h>
34 #include <connman/proxy.h>
35 #include <connman/log.h>
37 #include "gweb/gweb.h"
39 #define STATUS_URL "http://www.connman.net/online/status.html"
47 static void web_debug(const char *str, void *data)
49 connman_info("%s: %s\n", (const char *) data, str);
52 static gboolean web_result(GWebResult *result, gpointer user_data)
54 struct connman_location *location = user_data;
55 struct server_data *data = connman_location_get_data(location);
59 if (data->request_id == 0)
62 status = g_web_result_get_status(result);
64 /* If status header is not available, it is a portal */
65 if (g_web_result_get_header(result, "X-ConnMan-Status", &str) == FALSE)
68 DBG("status %u", status);
72 if (g_web_result_get_header(result, "X-ConnMan-Client-IP",
74 connman_info("Client-IP: %s", str);
76 if (g_web_result_get_header(result, "X-ConnMan-Client-Country",
78 connman_info("Client-Country: %s", str);
80 if (g_web_result_get_header(result, "X-ConnMan-Client-Region",
82 connman_info("Client-Region: %s", str);
84 connman_location_report_result(location,
85 CONNMAN_LOCATION_RESULT_ONLINE);
88 connman_location_report_result(location,
89 CONNMAN_LOCATION_RESULT_PORTAL);
92 connman_location_report_result(location,
93 CONNMAN_LOCATION_RESULT_UNKNOWN);
102 static void proxy_callback(const char *proxy, void *user_data)
104 struct connman_location *location = user_data;
105 struct server_data *data = connman_location_get_data(location);
107 DBG("proxy %s", proxy);
110 proxy = getenv("http_proxy");
113 if (proxy != NULL && g_strcmp0(proxy, "DIRECT") != 0)
114 g_web_set_proxy(data->web, proxy);
116 data->request_id = g_web_request_get(data->web, STATUS_URL,
117 web_result, location);
122 connman_location_unref(location);
125 static int location_detect(struct connman_location *location)
127 struct server_data *data;
128 struct connman_service *service;
129 enum connman_service_type service_type;
133 DBG("location %p", location);
135 service_type = connman_location_get_type(location);
137 switch (service_type) {
138 case CONNMAN_SERVICE_TYPE_ETHERNET:
139 case CONNMAN_SERVICE_TYPE_WIFI:
140 case CONNMAN_SERVICE_TYPE_WIMAX:
141 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
142 case CONNMAN_SERVICE_TYPE_CELLULAR:
144 case CONNMAN_SERVICE_TYPE_UNKNOWN:
145 case CONNMAN_SERVICE_TYPE_SYSTEM:
146 case CONNMAN_SERVICE_TYPE_GPS:
147 case CONNMAN_SERVICE_TYPE_VPN:
148 case CONNMAN_SERVICE_TYPE_GADGET:
152 interface = connman_location_get_interface(location);
153 if (interface == NULL)
156 DBG("interface %s", interface);
158 data = g_try_new0(struct server_data, 1);
164 connman_location_set_data(location, data);
166 data->web = g_web_new(0);
167 if (data->web == NULL) {
173 if (getenv("CONNMAN_WEB_DEBUG"))
174 g_web_set_debug(data->web, web_debug, "WEB");
176 g_web_set_accept(data->web, NULL);
177 g_web_set_user_agent(data->web, "ConnMan/%s", VERSION);
178 g_web_set_close_connection(data->web, TRUE);
180 connman_location_ref(location);
182 service = connman_location_get_service(location);
183 data->token = connman_proxy_lookup(interface, STATUS_URL,
184 service, proxy_callback, location);
186 if (data->token == 0) {
187 connman_location_unref(location);
197 static int location_finish(struct connman_location *location)
199 struct server_data *data = connman_location_get_data(location);
201 DBG("location %p", location);
203 connman_location_set_data(location, NULL);
205 if (data->request_id > 0)
206 g_web_cancel_request(data->web, data->request_id);
208 if (data->token > 0) {
209 connman_proxy_lookup_cancel(data->token);
210 connman_location_unref(location);
213 g_web_unref(data->web);
220 static struct connman_location_driver location = {
222 .type = CONNMAN_SERVICE_TYPE_WIFI,
223 .priority = CONNMAN_LOCATION_PRIORITY_HIGH,
224 .detect = location_detect,
225 .finish = location_finish,
228 static int portal_init(void)
230 return connman_location_driver_register(&location);
233 static void portal_exit(void)
235 connman_location_driver_unregister(&location);
238 CONNMAN_PLUGIN_DEFINE(portal, "Portal detection plugin", VERSION,
239 CONNMAN_PLUGIN_PRIORITY_DEFAULT, portal_init, portal_exit)