1d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt/* 2d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Hotspot 2.0 client - Web browser using wpadebug on Android 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(100); 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 wpabuf_put_str(resp, "User input completed"); 56d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 57d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (done) { 58d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_cancel_timeout(browser_timeout, NULL, NULL); 59d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_register_timeout(0, 500000, browser_timeout, &data, NULL); 60d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 61d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 62d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt http_request_send_and_deinit(req, resp); 63d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 64d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 65d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 66d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint hs20_web_browser(const char *url) 67d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 68d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char cmd[2000]; 69d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int ret; 70d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct http_server *http; 71d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct in_addr addr; 72d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct browser_data data; 73d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 74d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Launching wpadebug browser to %s", url); 75d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 76d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memset(&data, 0, sizeof(data)); 77d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 78d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = os_snprintf(cmd, sizeof(cmd), 79a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt "start -a android.action.MAIN " 80d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "-c android.intent.category.LAUNCHER " 81d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "-n w1.fi.wpadebug/.WpaWebViewActivity " 82d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "-e w1.fi.wpadebug.URL '%s'", url); 83d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ret < 0 || (size_t) ret >= sizeof(cmd)) { 84d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "Too long URL"); 85d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 86d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 87d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 88d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (eloop_init() < 0) { 89d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "eloop_init failed"); 90d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 91d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 92d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt addr.s_addr = htonl((127 << 24) | 1); 93d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt http = http_server_init(&addr, 12345, http_req, &data); 94d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (http == NULL) { 95d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "http_server_init failed"); 96d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_destroy(); 97d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 98d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 99d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 100a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt if (os_exec("/system/bin/am", cmd, 1) != 0) { 101d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Failed to launch wpadebug browser"); 102d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_cancel_timeout(browser_timeout, NULL, NULL); 103d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt http_server_deinit(http); 104d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_destroy(); 105d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 106d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 107d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 108d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_register_timeout(300, 0, browser_timeout, &data, NULL); 109d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_run(); 110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_cancel_timeout(browser_timeout, &data, NULL); 111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt http_server_deinit(http); 112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_destroy(); 113d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 114d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Closing Android browser"); 115a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt if (os_exec("/system/bin/am", 116a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt "start -a android.action.MAIN " 117a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt "-c android.intent.category.LAUNCHER " 118a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt "-n w1.fi.wpadebug/.WpaWebViewActivity " 119a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt "-e w1.fi.wpadebug.URL FINISH", 1) != 0) { 120d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Failed to close wpadebug browser"); 121d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 122d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 123d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return data.success; 124d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 125