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 struct http_server *http; 68d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct in_addr addr; 69d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct browser_data data; 70fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt pid_t pid; 71d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 72fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_INFO, "Launching system browser to %s", url); 73d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 74d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_memset(&data, 0, sizeof(data)); 75d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 76d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (eloop_init() < 0) { 77d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "eloop_init failed"); 78d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 79d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 80d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt addr.s_addr = htonl((127 << 24) | 1); 81d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt http = http_server_init(&addr, 12345, http_req, &data); 82d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (http == NULL) { 83d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "http_server_init failed"); 84d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_destroy(); 85d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 86d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 87d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 88fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt pid = fork(); 89fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (pid < 0) { 90fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "fork: %s", strerror(errno)); 91d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt http_server_deinit(http); 92d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_destroy(); 93d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 94d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 95d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 96fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (pid == 0) { 97fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt /* run the external command in the child process */ 98fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt char *argv[3]; 99fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 100fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt argv[0] = "browser-system"; 101fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt argv[1] = (void *) url; 102fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt argv[2] = NULL; 103fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 104fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt execv("/usr/bin/x-www-browser", argv); 105fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_ERROR, "execv: %s", strerror(errno)); 106fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt exit(0); 107fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt return -1; 108fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt } 109fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_register_timeout(120, 0, browser_timeout, &data, NULL); 111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_run(); 112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_cancel_timeout(browser_timeout, &data, NULL); 113d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt http_server_deinit(http); 114d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt eloop_destroy(); 115d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 116d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt /* TODO: Close browser */ 117d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 118d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return data.success; 119d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 120