summaryrefslogtreecommitdiff
path: root/src/wispr.c
diff options
context:
space:
mode:
authorTomasz Bursztyka <tomasz.bursztyka@linux.intel.com>2011-08-29 18:25:05 +0300
committerSamuel Ortiz <sameo@linux.intel.com>2011-09-12 19:45:38 +0200
commit3bbaf84997fc5720cd98839833e549153b3bfabc (patch)
tree4fa56635a4fadfe1da054402a9a39347965e3991 /src/wispr.c
parent72112bbb4bbf287096c43a7ecf61ed0d5757cfa3 (diff)
downloadconnman-3bbaf84997fc5720cd98839833e549153b3bfabc.tar.gz
connman-3bbaf84997fc5720cd98839833e549153b3bfabc.tar.bz2
connman-3bbaf84997fc5720cd98839833e549153b3bfabc.zip
wispr: Handle WISPr messages and apply relevant states
Diffstat (limited to 'src/wispr.c')
-rw-r--r--src/wispr.c157
1 files changed, 139 insertions, 18 deletions
diff --git a/src/wispr.c b/src/wispr.c
index 4cda5ed0..dd093bc7 100644
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -45,6 +45,13 @@ struct connman_wispr_message {
char *location_name;
};
+enum connman_wispr_result {
+ CONNMAN_WISPR_RESULT_UNKNOWN = 0,
+ CONNMAN_WISPR_RESULT_LOGIN = 1,
+ CONNMAN_WISPR_RESULT_ONLINE = 2,
+ CONNMAN_WISPR_RESULT_FAILED = 3,
+};
+
struct connman_wispr_portal_context {
struct connman_service *service;
enum connman_ipconfig_type type;
@@ -57,6 +64,8 @@ struct connman_wispr_portal_context {
/* WISPr specific */
GWebParser *wispr_parser;
struct connman_wispr_message wispr_msg;
+
+ enum connman_wispr_result wispr_result;
};
struct connman_wispr_portal {
@@ -64,6 +73,8 @@ struct connman_wispr_portal {
struct connman_wispr_portal_context *ipv6_context;
};
+static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data);
+
static GHashTable *wispr_portal_list = NULL;
static void connman_wispr_message_init(struct connman_wispr_message *msg)
@@ -131,6 +142,54 @@ static void free_connman_wispr_portal(gpointer data)
g_free(wispr_portal);
}
+static const char *message_type_to_string(int message_type)
+{
+ switch (message_type) {
+ case 100:
+ return "Initial redirect message";
+ case 110:
+ return "Proxy notification";
+ case 120:
+ return "Authentication notification";
+ case 130:
+ return "Logoff notification";
+ case 140:
+ return "Response to Authentication Poll";
+ case 150:
+ return "Response to Abort Login";
+ }
+
+ return NULL;
+}
+
+static const char *response_code_to_string(int response_code)
+{
+ switch (response_code) {
+ case 0:
+ return "No error";
+ case 50:
+ return "Login succeeded";
+ case 100:
+ return "Login failed";
+ case 102:
+ return "RADIUS server error/timeout";
+ case 105:
+ return "RADIUS server not enabled";
+ case 150:
+ return "Logoff succeeded";
+ case 151:
+ return "Login aborted";
+ case 200:
+ return "Proxy detection/repeat operation";
+ case 201:
+ return "Authentication pending";
+ case 255:
+ return "Access gateway internal error";
+ }
+
+ return NULL;
+}
+
static struct {
const char *str;
enum {
@@ -284,6 +343,8 @@ static void web_debug(const char *str, void *data)
static void wispr_portal_error(struct connman_wispr_portal_context *wp_context)
{
DBG("Failed to proceed wispr/portal web request");
+
+ wp_context->wispr_result = CONNMAN_WISPR_RESULT_FAILED;
}
static void portal_manage_status(GWebResult *result,
@@ -311,6 +372,70 @@ static void portal_manage_status(GWebResult *result,
wp_context->type);
}
+static void wispr_portal_request_portal(struct connman_wispr_portal_context *wp_context)
+{
+ DBG("");
+
+ wp_context->request_id = g_web_request_get(wp_context->web,
+ STATUS_URL, wispr_portal_web_result, wp_context);
+
+ if (wp_context->request_id == 0)
+ wispr_portal_error(wp_context);
+}
+
+static gboolean wispr_manage_message(GWebResult *result,
+ struct connman_wispr_portal_context *wp_context)
+{
+ DBG("Message type: %s (%d)",
+ message_type_to_string(wp_context->wispr_msg.message_type),
+ wp_context->wispr_msg.message_type);
+ DBG("Response code: %s (%d)",
+ response_code_to_string(wp_context->wispr_msg.response_code),
+ wp_context->wispr_msg.response_code);
+
+ if (wp_context->wispr_msg.access_procedure != NULL)
+ DBG("Access procedure: %s",
+ wp_context->wispr_msg.access_procedure);
+ if (wp_context->wispr_msg.access_location != NULL)
+ DBG("Access location: %s",
+ wp_context->wispr_msg.access_location);
+ if (wp_context->wispr_msg.location_name != NULL)
+ DBG("Location name: %s",
+ wp_context->wispr_msg.location_name);
+ if (wp_context->wispr_msg.login_url != NULL)
+ DBG("Login URL: %s", wp_context->wispr_msg.login_url);
+ if (wp_context->wispr_msg.abort_login_url != NULL)
+ DBG("Abort login URL: %s",
+ wp_context->wispr_msg.abort_login_url);
+ if (wp_context->wispr_msg.logoff_url != NULL)
+ DBG("Logoff URL: %s", wp_context->wispr_msg.logoff_url);
+
+ switch (wp_context->wispr_msg.message_type) {
+ case 100:
+ DBG("Login required");
+
+ wp_context->wispr_result = CONNMAN_WISPR_RESULT_LOGIN;
+
+ break;
+ case 120: /* Falling down */
+ case 140:
+ if (wp_context->wispr_msg.response_code == 50) {
+ wp_context->wispr_result = CONNMAN_WISPR_RESULT_ONLINE;
+
+ wispr_portal_request_portal(wp_context);
+
+ return TRUE;
+ } else
+ wispr_portal_error(wp_context);
+
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
{
struct connman_wispr_portal_context *wp_context = user_data;
@@ -325,15 +450,22 @@ static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
if (wp_context->request_id == 0)
return FALSE;
- g_web_result_get_chunk(result, &chunk, &length);
+ if (wp_context->wispr_result != CONNMAN_WISPR_RESULT_ONLINE) {
+ g_web_result_get_chunk(result, &chunk, &length);
- if (length > 0) {
- g_web_parser_feed_data(wp_context->wispr_parser,
- chunk, length);
- return TRUE;
- }
+ if (length > 0) {
+ g_web_parser_feed_data(wp_context->wispr_parser,
+ chunk, length);
+ return TRUE;
+ }
- g_web_parser_end_data(wp_context->wispr_parser);
+ g_web_parser_end_data(wp_context->wispr_parser);
+
+ if (wp_context->wispr_msg.message_type >= 0) {
+ if (wispr_manage_message(result, wp_context) == TRUE)
+ goto done;
+ }
+ }
status = g_web_result_get_status(result);
@@ -374,17 +506,6 @@ done:
return FALSE;
}
-static void wispr_portal_request_portal(struct connman_wispr_portal_context *wp_context)
-{
- DBG("");
-
- wp_context->request_id = g_web_request_get(wp_context->web,
- STATUS_URL, wispr_portal_web_result, wp_context);
-
- if (wp_context->request_id == 0)
- wispr_portal_error(wp_context);
-}
-
static void proxy_callback(const char *proxy, void *user_data)
{
struct connman_wispr_portal_context *wp_context = user_data;