1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker * Hotspot 2.0 client - Web browser using Android browser
3*03f9172cSAndroid Build Coastguard Worker * Copyright (c) 2013, Qualcomm Atheros, Inc.
4*03f9172cSAndroid Build Coastguard Worker *
5*03f9172cSAndroid Build Coastguard Worker * This software may be distributed under the terms of the BSD license.
6*03f9172cSAndroid Build Coastguard Worker * See README for more details.
7*03f9172cSAndroid Build Coastguard Worker */
8*03f9172cSAndroid Build Coastguard Worker
9*03f9172cSAndroid Build Coastguard Worker #include "includes.h"
10*03f9172cSAndroid Build Coastguard Worker
11*03f9172cSAndroid Build Coastguard Worker #include "common.h"
12*03f9172cSAndroid Build Coastguard Worker #include "utils/eloop.h"
13*03f9172cSAndroid Build Coastguard Worker #include "wps/http_server.h"
14*03f9172cSAndroid Build Coastguard Worker #include "browser.h"
15*03f9172cSAndroid Build Coastguard Worker
16*03f9172cSAndroid Build Coastguard Worker
17*03f9172cSAndroid Build Coastguard Worker struct browser_data {
18*03f9172cSAndroid Build Coastguard Worker int success;
19*03f9172cSAndroid Build Coastguard Worker };
20*03f9172cSAndroid Build Coastguard Worker
21*03f9172cSAndroid Build Coastguard Worker
browser_timeout(void * eloop_data,void * user_ctx)22*03f9172cSAndroid Build Coastguard Worker static void browser_timeout(void *eloop_data, void *user_ctx)
23*03f9172cSAndroid Build Coastguard Worker {
24*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "Timeout on waiting browser interaction to "
25*03f9172cSAndroid Build Coastguard Worker "complete");
26*03f9172cSAndroid Build Coastguard Worker eloop_terminate();
27*03f9172cSAndroid Build Coastguard Worker }
28*03f9172cSAndroid Build Coastguard Worker
29*03f9172cSAndroid Build Coastguard Worker
http_req(void * ctx,struct http_request * req)30*03f9172cSAndroid Build Coastguard Worker static void http_req(void *ctx, struct http_request *req)
31*03f9172cSAndroid Build Coastguard Worker {
32*03f9172cSAndroid Build Coastguard Worker struct browser_data *data = ctx;
33*03f9172cSAndroid Build Coastguard Worker struct wpabuf *resp;
34*03f9172cSAndroid Build Coastguard Worker const char *url;
35*03f9172cSAndroid Build Coastguard Worker int done = 0;
36*03f9172cSAndroid Build Coastguard Worker
37*03f9172cSAndroid Build Coastguard Worker url = http_request_get_uri(req);
38*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "Browser response received: %s", url);
39*03f9172cSAndroid Build Coastguard Worker
40*03f9172cSAndroid Build Coastguard Worker if (os_strcmp(url, "/") == 0) {
41*03f9172cSAndroid Build Coastguard Worker data->success = 1;
42*03f9172cSAndroid Build Coastguard Worker done = 1;
43*03f9172cSAndroid Build Coastguard Worker } else if (os_strncmp(url, "/osu/", 5) == 0) {
44*03f9172cSAndroid Build Coastguard Worker data->success = atoi(url + 5);
45*03f9172cSAndroid Build Coastguard Worker done = 1;
46*03f9172cSAndroid Build Coastguard Worker }
47*03f9172cSAndroid Build Coastguard Worker
48*03f9172cSAndroid Build Coastguard Worker resp = wpabuf_alloc(1);
49*03f9172cSAndroid Build Coastguard Worker if (resp == NULL) {
50*03f9172cSAndroid Build Coastguard Worker http_request_deinit(req);
51*03f9172cSAndroid Build Coastguard Worker if (done)
52*03f9172cSAndroid Build Coastguard Worker eloop_terminate();
53*03f9172cSAndroid Build Coastguard Worker return;
54*03f9172cSAndroid Build Coastguard Worker }
55*03f9172cSAndroid Build Coastguard Worker
56*03f9172cSAndroid Build Coastguard Worker if (done) {
57*03f9172cSAndroid Build Coastguard Worker eloop_cancel_timeout(browser_timeout, NULL, NULL);
58*03f9172cSAndroid Build Coastguard Worker eloop_register_timeout(0, 500000, browser_timeout, &data, NULL);
59*03f9172cSAndroid Build Coastguard Worker }
60*03f9172cSAndroid Build Coastguard Worker
61*03f9172cSAndroid Build Coastguard Worker http_request_send_and_deinit(req, resp);
62*03f9172cSAndroid Build Coastguard Worker }
63*03f9172cSAndroid Build Coastguard Worker
64*03f9172cSAndroid Build Coastguard Worker
hs20_web_browser(const char * url,int ignore_tls)65*03f9172cSAndroid Build Coastguard Worker int hs20_web_browser(const char *url, int ignore_tls)
66*03f9172cSAndroid Build Coastguard Worker {
67*03f9172cSAndroid Build Coastguard Worker struct http_server *http;
68*03f9172cSAndroid Build Coastguard Worker struct in_addr addr;
69*03f9172cSAndroid Build Coastguard Worker struct browser_data data;
70*03f9172cSAndroid Build Coastguard Worker pid_t pid;
71*03f9172cSAndroid Build Coastguard Worker
72*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "Launching Android browser to %s", url);
73*03f9172cSAndroid Build Coastguard Worker
74*03f9172cSAndroid Build Coastguard Worker os_memset(&data, 0, sizeof(data));
75*03f9172cSAndroid Build Coastguard Worker
76*03f9172cSAndroid Build Coastguard Worker if (eloop_init() < 0) {
77*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_ERROR, "eloop_init failed");
78*03f9172cSAndroid Build Coastguard Worker return -1;
79*03f9172cSAndroid Build Coastguard Worker }
80*03f9172cSAndroid Build Coastguard Worker addr.s_addr = htonl((127 << 24) | 1);
81*03f9172cSAndroid Build Coastguard Worker http = http_server_init(&addr, 12345, http_req, &data);
82*03f9172cSAndroid Build Coastguard Worker if (http == NULL) {
83*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_ERROR, "http_server_init failed");
84*03f9172cSAndroid Build Coastguard Worker eloop_destroy();
85*03f9172cSAndroid Build Coastguard Worker return -1;
86*03f9172cSAndroid Build Coastguard Worker }
87*03f9172cSAndroid Build Coastguard Worker
88*03f9172cSAndroid Build Coastguard Worker pid = fork();
89*03f9172cSAndroid Build Coastguard Worker if (pid < 0) {
90*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_ERROR, "fork: %s", strerror(errno));
91*03f9172cSAndroid Build Coastguard Worker http_server_deinit(http);
92*03f9172cSAndroid Build Coastguard Worker eloop_destroy();
93*03f9172cSAndroid Build Coastguard Worker return -1;
94*03f9172cSAndroid Build Coastguard Worker }
95*03f9172cSAndroid Build Coastguard Worker
96*03f9172cSAndroid Build Coastguard Worker if (pid == 0) {
97*03f9172cSAndroid Build Coastguard Worker /* run the external command in the child process */
98*03f9172cSAndroid Build Coastguard Worker char *argv[7];
99*03f9172cSAndroid Build Coastguard Worker
100*03f9172cSAndroid Build Coastguard Worker argv[0] = "browser-android";
101*03f9172cSAndroid Build Coastguard Worker argv[1] = "start";
102*03f9172cSAndroid Build Coastguard Worker argv[2] = "-a";
103*03f9172cSAndroid Build Coastguard Worker argv[3] = "android.intent.action.VIEW";
104*03f9172cSAndroid Build Coastguard Worker argv[4] = "-d";
105*03f9172cSAndroid Build Coastguard Worker argv[5] = (void *) url;
106*03f9172cSAndroid Build Coastguard Worker argv[6] = NULL;
107*03f9172cSAndroid Build Coastguard Worker
108*03f9172cSAndroid Build Coastguard Worker execv("/system/bin/am", argv);
109*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_ERROR, "execv: %s", strerror(errno));
110*03f9172cSAndroid Build Coastguard Worker exit(0);
111*03f9172cSAndroid Build Coastguard Worker return -1;
112*03f9172cSAndroid Build Coastguard Worker }
113*03f9172cSAndroid Build Coastguard Worker
114*03f9172cSAndroid Build Coastguard Worker eloop_register_timeout(30, 0, browser_timeout, &data, NULL);
115*03f9172cSAndroid Build Coastguard Worker eloop_run();
116*03f9172cSAndroid Build Coastguard Worker eloop_cancel_timeout(browser_timeout, &data, NULL);
117*03f9172cSAndroid Build Coastguard Worker http_server_deinit(http);
118*03f9172cSAndroid Build Coastguard Worker eloop_destroy();
119*03f9172cSAndroid Build Coastguard Worker
120*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "Closing Android browser");
121*03f9172cSAndroid Build Coastguard Worker if (system("/system/bin/input keyevent KEYCODE_HOME") != 0) {
122*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "Failed to inject keyevent");
123*03f9172cSAndroid Build Coastguard Worker }
124*03f9172cSAndroid Build Coastguard Worker
125*03f9172cSAndroid Build Coastguard Worker return data.success;
126*03f9172cSAndroid Build Coastguard Worker }
127