fc1fe905a56845d477b6b699428b33cf710c710e
[framework/connectivity/connman.git] / tools / wispr.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 <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <signal.h>
30
31 #include <gweb/gweb.h>
32
33 #define DEFAULT_URL  "http://www.connman.net/online/status.html"
34
35 static GTimer *timer;
36
37 static GMainLoop *main_loop;
38
39 static void web_debug(const char *str, void *data)
40 {
41         g_print("%s: %s\n", (const char *) data, str);
42 }
43
44 static void sig_term(int sig)
45 {
46         g_main_loop_quit(main_loop);
47 }
48
49 enum wispr_elements {
50         WISPR_NONE,
51         WISPR_ACCESS_PROCEDURE,
52         WISPR_ACCESS_LOCATION,
53         WISPR_LOCATION_NAME,
54         WISPR_LOGIN_URL,
55         WISPR_ABORT_LOGIN_URL,
56         WISPR_MESSAGE_TYPE,
57         WISPR_RESPONSE_CODE,
58         WISPR_NEXT_URL,
59         WISPR_DELAY,
60         WISPR_REPLY_MESSAGE,
61         WISPR_LOGIN_RESULTS_URL,
62         WISPR_LOGOFF_URL,
63 };
64
65 static enum wispr_elements current_element = WISPR_NONE;
66
67 static void start_element_handler(GMarkupParseContext *context,
68                                         const gchar *element_name,
69                                         const gchar **attribute_names,
70                                         const gchar **attribute_values,
71                                         gpointer user_data, GError **error)
72 {
73         if (g_str_equal(element_name, "AccessProcedure") == TRUE)
74                 current_element = WISPR_ACCESS_PROCEDURE;
75         else if (g_str_equal(element_name, "AccessLocation") == TRUE)
76                 current_element = WISPR_ACCESS_LOCATION;
77         else if (g_str_equal(element_name, "LocationName") == TRUE)
78                 current_element = WISPR_LOCATION_NAME;
79         else if (g_str_equal(element_name, "LoginURL") == TRUE)
80                 current_element = WISPR_LOGIN_URL;
81         else if (g_str_equal(element_name, "AbortLoginURL") == TRUE)
82                 current_element = WISPR_ABORT_LOGIN_URL;
83         else if (g_str_equal(element_name, "MessageType") == TRUE)
84                 current_element = WISPR_MESSAGE_TYPE;
85         else if (g_str_equal(element_name, "ResponseCode") == TRUE)
86                 current_element = WISPR_RESPONSE_CODE;
87         else if (g_str_equal(element_name, "NextURL") == TRUE)
88                 current_element = WISPR_NEXT_URL;
89         else if (g_str_equal(element_name, "Delay") == TRUE)
90                 current_element = WISPR_DELAY;
91         else if (g_str_equal(element_name, "ReplyMessage") == TRUE)
92                 current_element = WISPR_REPLY_MESSAGE;
93         else if (g_str_equal(element_name, "LoginResultsURL") == TRUE)
94                 current_element = WISPR_LOGIN_RESULTS_URL;
95         else if (g_str_equal(element_name, "LogoffURL") == TRUE)
96                 current_element = WISPR_LOGOFF_URL;
97 }
98
99 static void end_element_handler(GMarkupParseContext *context,
100                                         const gchar *element_name,
101                                         gpointer user_data, GError **error)
102 {
103         current_element = WISPR_NONE;
104 }
105
106 static void text_handler(GMarkupParseContext *context,
107                                         const gchar *text, gsize text_len,
108                                         gpointer user_data, GError **error)
109 {
110         int value;
111
112         switch (current_element) {
113         case WISPR_NONE:
114                 break;
115         case WISPR_ACCESS_PROCEDURE:
116                 printf("Access procedure: %s\n", text);
117                 break;
118         case WISPR_ACCESS_LOCATION:
119                 printf("Access location: %s\n", text);
120                 break;
121         case WISPR_LOCATION_NAME:
122                 printf("Location name: %s\n", text);
123                 break;
124         case WISPR_LOGIN_URL:
125                 printf("Login URL: %s\n", text);
126                 break;
127         case WISPR_ABORT_LOGIN_URL:
128                 printf("Abort login URL: %s\n", text);
129                 break;
130         case WISPR_MESSAGE_TYPE:
131                 value = atoi(text);
132                 printf("Message type: %d\n", value);
133                 switch (value) {
134                 case 100:
135                         printf("  Initial redirect message\n");
136                         break;
137                 case 110:
138                         printf("  Proxy notification\n");
139                         break;
140                 case 120:
141                         printf("  Authentication notification\n");
142                         break;
143                 case 130:
144                         printf("  Logoff notification\n");
145                         break;
146                 case 140:
147                         printf("  Response to Authentication Poll\n");
148                         break;
149                 case 150:
150                         printf("  Response to Abort Login\n");
151                         break;
152                 }
153                 break;
154         case WISPR_RESPONSE_CODE:
155                 value = atoi(text);
156                 printf("Response code: %d\n", value);
157                 switch (value) {
158                 case 0:
159                         printf("  No error\n");
160                         break;
161                 case 50:
162                         printf("  Login succeeded (Access ACCEPT)\n");
163                         break;
164                 case 100:
165                         printf("  Login failed (Access REJECT)\n");
166                         break;
167                 case 102:
168                         printf("  RADIUS server error/timeout\n");
169                         break;
170                 case 105:
171                         printf("  RADIUS server not enabled\n");
172                         break;
173                 case 150:
174                         printf("  Logoff succeeded\n");
175                         break;
176                 case 151:
177                         printf("  Login aborted\n");
178                         break;
179                 case 200:
180                         printf("  Proxy detection/repeat operation\n");
181                         break;
182                 case 201:
183                         printf("  Authentication pending\n");
184                         break;
185                 case 255:
186                         printf("  Access gateway internal error\n");
187                         break;
188                 }
189                 break;
190         case WISPR_NEXT_URL:
191                 printf("Next URL: %s\n", text);
192                 break;
193         case WISPR_DELAY:
194                 value = atoi(text);
195                 printf("Delay: %d seconds\n", value);
196                 break;
197         case WISPR_REPLY_MESSAGE:
198                 printf("Reply message: %s\n", text);
199                 break;
200         case WISPR_LOGIN_RESULTS_URL:
201                 printf("Login results URL: %s\n", text);
202                 break;
203         case WISPR_LOGOFF_URL:
204                 printf("Logoff URL: %s\n", text);
205                 break;
206         }
207 }
208
209 static void error_handler(GMarkupParseContext *context,
210                                         GError *error, gpointer user_data)
211 {
212         printf("%s\n", error->message);
213 }
214
215 static const GMarkupParser wispr_parser = {
216         start_element_handler,
217         end_element_handler,
218         text_handler,
219         NULL,
220         error_handler,
221 };
222
223 static void parser_callback(const char *str, gpointer user_data)
224 {
225         GMarkupParseContext *context;
226         gboolean result;
227
228         //printf("%s\n", str);
229
230         context = g_markup_parse_context_new(&wispr_parser,
231                                 G_MARKUP_TREAT_CDATA_AS_TEXT, NULL, NULL);
232
233         result = g_markup_parse_context_parse(context, str, strlen(str), NULL);
234
235         result = g_markup_parse_context_end_parse(context, NULL);
236
237         g_markup_parse_context_free(context);
238 }
239
240 static guint request_id;
241 static GWebParser *request_parser;
242
243 static gboolean web_result(GWebResult *result, gpointer user_data)
244 {
245         const guint8 *chunk;
246         gsize length;
247         guint16 status;
248         gdouble elapsed;
249
250         status = g_web_result_get_status(result);
251         if (status == 200)
252                 goto done;
253
254         g_web_result_get_chunk(result, &chunk, &length);
255
256         if (length > 0) {
257                 //printf("%s\n", (char *) chunk);
258                 g_web_parser_feed_data(request_parser, chunk, length);
259                 return TRUE;
260         }
261
262         g_web_parser_end_data(request_parser);
263
264 done:
265         g_print("status: %03u\n", status);
266
267         elapsed = g_timer_elapsed(timer, NULL);
268
269         g_print("elapse: %f seconds\n", elapsed);
270
271         g_main_loop_quit(main_loop);
272
273         return FALSE;
274 }
275
276 static gboolean option_debug = FALSE;
277 static gchar *option_nameserver = NULL;
278 static gchar *option_url = NULL;
279
280 static GOptionEntry options[] = {
281         { "debug", 'd', 0, G_OPTION_ARG_NONE, &option_debug,
282                                         "Enable debug output" },
283         { "nameserver", 'n', 0, G_OPTION_ARG_STRING, &option_nameserver,
284                                         "Specify nameserver", "ADDRESS" },
285         { "url", 'u', 0, G_OPTION_ARG_STRING, &option_url,
286                                         "Specify arbitrary request", "URL" },
287         { NULL },
288 };
289
290 int main(int argc, char *argv[])
291 {
292         GOptionContext *context;
293         GError *error = NULL;
294         struct sigaction sa;
295         GWeb *web;
296         int index = 0;
297
298         context = g_option_context_new(NULL);
299         g_option_context_add_main_entries(context, options, NULL);
300
301         if (g_option_context_parse(context, &argc, &argv, &error) == FALSE) {
302                 if (error != NULL) {
303                         g_printerr("%s\n", error->message);
304                         g_error_free(error);
305                 } else
306                         g_printerr("An unknown error occurred\n");
307                 return 1;
308         }
309
310         g_option_context_free(context);
311
312         web = g_web_new(index);
313         if (web == NULL) {
314                 fprintf(stderr, "Failed to create web service\n");
315                 return 1;
316         }
317
318         if (option_debug == TRUE)
319                 g_web_set_debug(web, web_debug, "WEB");
320
321         main_loop = g_main_loop_new(NULL, FALSE);
322
323         if (option_nameserver != NULL) {
324                 g_web_add_nameserver(web, option_nameserver);
325                 g_free(option_nameserver);
326         }
327
328         g_web_set_accept(web, NULL);
329         g_web_set_user_agent(web, "SmartClient/%s wispr", VERSION);
330         g_web_set_close_connection(web, TRUE);
331
332         if (option_url == NULL)
333                 option_url = g_strdup(DEFAULT_URL);
334
335         timer = g_timer_new();
336
337         request_parser = g_web_parser_new("<WISPAccessGatewayParam",
338                                                 "WISPAccessGatewayParam>",
339                                                 parser_callback, NULL);
340
341         g_web_parser_ref(request_parser);
342         g_web_parser_unref(request_parser);
343
344         request_id = g_web_request(web, G_WEB_METHOD_GET, option_url,
345                                                         web_result, NULL);
346
347         g_free(option_url);
348
349         if (request_id == 0) {
350                 fprintf(stderr, "Failed to start request\n");
351                 return 1;
352         }
353
354         memset(&sa, 0, sizeof(sa));
355         sa.sa_handler = sig_term;
356         sigaction(SIGINT, &sa, NULL);
357         sigaction(SIGTERM, &sa, NULL);
358
359         g_main_loop_run(main_loop);
360
361         g_timer_destroy(timer);
362
363         g_web_unref(web);
364
365         g_main_loop_unref(main_loop);
366
367         return 0;
368 }