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