wifi: Make gsupplicant debug depend on CONNMAN_GSUPPLICANT_DEBUG
[platform/upstream/connman.git] / plugins / portal.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
6  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <errno.h>
27 #include <stdlib.h>
28
29 #include <glib.h>
30
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>
36
37 #include "gweb/gweb.h"
38
39 #define STATUS_URL  "http://www.connman.net/online/status.html"
40
41 struct server_data {
42         GWeb *web;
43         guint request_id;
44 };
45
46 static void web_debug(const char *str, void *data)
47 {
48         connman_info("%s: %s\n", (const char *) data, str);
49 }
50
51 static gboolean web_result(GWebResult *result, gpointer user_data)
52 {
53         struct connman_location *location = user_data;
54         struct server_data *data = connman_location_get_data(location);
55         guint16 status;
56
57         if (data->request_id == 0)
58                 return FALSE;
59
60         status = g_web_result_get_status(result);
61
62         DBG("status %u", status);
63
64         switch (status) {
65         case 200:
66                 connman_location_report_result(location,
67                                         CONNMAN_LOCATION_RESULT_ONLINE);
68                 break;
69         case 302:
70                 connman_location_report_result(location,
71                                         CONNMAN_LOCATION_RESULT_PORTAL);
72                 break;
73         default:
74                 connman_location_report_result(location,
75                                         CONNMAN_LOCATION_RESULT_UNKNOWN);
76                 break;
77         }
78
79         data->request_id = 0;
80
81         return FALSE;
82 }
83
84 static void proxy_callback(const char *proxy, void *user_data)
85 {
86         struct connman_location *location = user_data;
87         struct server_data *data = connman_location_get_data(location);
88
89         DBG("proxy %s", proxy);
90
91         if (proxy == NULL)
92                 proxy = getenv("http_proxy");
93
94         if (data != NULL) {
95                 g_web_set_proxy(data->web, proxy);
96
97                 data->request_id = g_web_request_get(data->web, STATUS_URL,
98                                                         web_result, location);
99         }
100
101         connman_location_unref(location);
102 }
103
104 static int location_detect(struct connman_location *location)
105 {
106         struct server_data *data;
107         enum connman_service_type service_type;
108         const char *interface;
109         int err;
110
111         DBG("location %p", location);
112
113         service_type = connman_location_get_type(location);
114
115         switch (service_type) {
116         case CONNMAN_SERVICE_TYPE_ETHERNET:
117         case CONNMAN_SERVICE_TYPE_WIFI:
118         case CONNMAN_SERVICE_TYPE_WIMAX:
119         case CONNMAN_SERVICE_TYPE_BLUETOOTH:
120         case CONNMAN_SERVICE_TYPE_CELLULAR:
121                 break;
122         case CONNMAN_SERVICE_TYPE_UNKNOWN:
123         case CONNMAN_SERVICE_TYPE_SYSTEM:
124         case CONNMAN_SERVICE_TYPE_GPS:
125         case CONNMAN_SERVICE_TYPE_VPN:
126         case CONNMAN_SERVICE_TYPE_GADGET:
127                 return -EOPNOTSUPP;
128         }
129
130         interface = connman_location_get_interface(location);
131         if (interface == NULL)
132                 return -EINVAL;
133
134         DBG("interface %s", interface);
135
136         data = g_try_new0(struct server_data, 1);
137         if (data == NULL)
138                 return -ENOMEM;
139
140         connman_location_set_data(location, data);
141
142         data->web = g_web_new(0);
143         if (data->web == NULL) {
144                 g_free(data);
145                 return -ENOMEM;
146         }
147
148         if (getenv("CONNMAN_WEB_DEBUG"))
149                 g_web_set_debug(data->web, web_debug, "WEB");
150
151         g_web_set_accept(data->web, NULL);
152         g_web_set_user_agent(data->web, "ConnMan/%s", VERSION);
153         g_web_set_close_connection(data->web, TRUE);
154
155         err = connman_proxy_lookup(interface, STATUS_URL,
156                                         proxy_callback, location);
157         if (err < 0)
158                 return err;
159
160         connman_location_ref(location);
161
162         return 0;
163 }
164
165 static int location_finish(struct connman_location *location)
166 {
167         struct server_data *data = connman_location_get_data(location);
168
169         DBG("location %p", location);
170
171         connman_location_set_data(location, NULL);
172
173         if (data->request_id > 0)
174                 g_web_cancel_request(data->web, data->request_id);
175
176         g_web_unref(data->web);
177
178         g_free(data);
179
180         return 0;
181 }
182
183 static struct connman_location_driver location = {
184         .name           = "portal",
185         .type           = CONNMAN_SERVICE_TYPE_WIFI,
186         .priority       = CONNMAN_LOCATION_PRIORITY_HIGH,
187         .detect         = location_detect,
188         .finish         = location_finish,
189 };
190
191 static int portal_init(void)
192 {
193         return connman_location_driver_register(&location);
194 }
195
196 static void portal_exit(void)
197 {
198         connman_location_driver_unregister(&location);
199 }
200
201 CONNMAN_PLUGIN_DEFINE(portal, "Portal detection plugin", VERSION,
202                 CONNMAN_PLUGIN_PRIORITY_DEFAULT, portal_init, portal_exit)