1d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt/*
2d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Hotspot 2.0 client - Web browser using system browser
3d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Copyright (c) 2013, Qualcomm Atheros, Inc.
4d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *
5d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * This software may be distributed under the terms of the BSD license.
6d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * See README for more details.
7d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */
8d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
9d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "includes.h"
10d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
11d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "common.h"
12d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "utils/eloop.h"
13d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "wps/http_server.h"
14d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "browser.h"
15d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
16d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
17d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstruct browser_data {
18d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int success;
19d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt};
20d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
21d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
22d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void browser_timeout(void *eloop_data, void *user_ctx)
23d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
24d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Timeout on waiting browser interaction to "
25d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		   "complete");
26d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	eloop_terminate();
27d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
28d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
29d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
30d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void http_req(void *ctx, struct http_request *req)
31d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
32d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct browser_data *data = ctx;
33d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct wpabuf *resp;
34d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	const char *url;
35d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int done = 0;
36d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
37d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	url = http_request_get_uri(req);
38d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Browser response received: %s", url);
39d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
40d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strcmp(url, "/") == 0) {
41d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		data->success = 1;
42d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		done = 1;
43d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	} else if (os_strncmp(url, "/osu/", 5) == 0) {
44d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		data->success = atoi(url + 5);
45d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		done = 1;
46d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
47d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
48d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	resp = wpabuf_alloc(1);
49d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (resp == NULL) {
50d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		http_request_deinit(req);
51d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (done)
52d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			eloop_terminate();
53d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
54d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
55d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
56d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (done) {
57d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		eloop_cancel_timeout(browser_timeout, NULL, NULL);
58d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		eloop_register_timeout(0, 500000, browser_timeout, &data, NULL);
59d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
60d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
61d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	http_request_send_and_deinit(req, resp);
62d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
63d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
64d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
65d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint hs20_web_browser(const char *url)
66d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
67d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char cmd[2000];
68d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int ret;
69d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct http_server *http;
70d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct in_addr addr;
71d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	struct browser_data data;
72d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
73d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Launching Android browser to %s", url);
74d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
75d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_memset(&data, 0, sizeof(data));
76d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
77d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ret = os_snprintf(cmd, sizeof(cmd), "x-www-browser '%s' &", url);
78d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ret < 0 || (size_t) ret >= sizeof(cmd)) {
79d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_ERROR, "Too long URL");
80d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
81d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
82d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
83d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (eloop_init() < 0) {
84d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_ERROR, "eloop_init failed");
85d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
86d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
87d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	addr.s_addr = htonl((127 << 24) | 1);
88d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	http = http_server_init(&addr, 12345, http_req, &data);
89d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (http == NULL) {
90d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_ERROR, "http_server_init failed");
91d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		eloop_destroy();
92d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
93d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
94d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
95a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt	if (os_exec("/usr/bin/x-www-browser", url, 0) != 0) {
96d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Failed to launch browser");
97d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		eloop_cancel_timeout(browser_timeout, NULL, NULL);
98d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		http_server_deinit(http);
99d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		eloop_destroy();
100d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
101d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
102d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
103d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	eloop_register_timeout(120, 0, browser_timeout, &data, NULL);
104d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	eloop_run();
105d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	eloop_cancel_timeout(browser_timeout, &data, NULL);
106d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	http_server_deinit(http);
107d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	eloop_destroy();
108d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
109d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	/* TODO: Close browser */
110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return data.success;
112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
113