1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * Captive portal detect for Secure Streams 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com> 7d4afb5ceSopenharmony_ci * 8d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 9d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to 10d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the 11d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 13d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions: 14d4afb5ceSopenharmony_ci * 15d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in 16d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software. 17d4afb5ceSopenharmony_ci * 18d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24d4afb5ceSopenharmony_ci * IN THE SOFTWARE. 25d4afb5ceSopenharmony_ci */ 26d4afb5ceSopenharmony_ci 27d4afb5ceSopenharmony_ci#include <private-lib-core.h> 28d4afb5ceSopenharmony_ci 29d4afb5ceSopenharmony_citypedef struct ss_cpd { 30d4afb5ceSopenharmony_ci struct lws_ss_handle *ss; 31d4afb5ceSopenharmony_ci void *opaque_data; 32d4afb5ceSopenharmony_ci /* ... application specific state ... */ 33d4afb5ceSopenharmony_ci 34d4afb5ceSopenharmony_ci lws_sorted_usec_list_t sul; 35d4afb5ceSopenharmony_ci} ss_cpd_t; 36d4afb5ceSopenharmony_ci 37d4afb5ceSopenharmony_cistatic lws_ss_state_return_t 38d4afb5ceSopenharmony_ciss_cpd_state(void *userobj, void *sh, lws_ss_constate_t state, 39d4afb5ceSopenharmony_ci lws_ss_tx_ordinal_t ack) 40d4afb5ceSopenharmony_ci{ 41d4afb5ceSopenharmony_ci ss_cpd_t *m = (ss_cpd_t *)userobj; 42d4afb5ceSopenharmony_ci struct lws_context *cx = (struct lws_context *)m->opaque_data; 43d4afb5ceSopenharmony_ci 44d4afb5ceSopenharmony_ci lwsl_ss_info(m->ss, "%s, ord 0x%x\n", lws_ss_state_name((int)state), 45d4afb5ceSopenharmony_ci (unsigned int)ack); 46d4afb5ceSopenharmony_ci 47d4afb5ceSopenharmony_ci switch (state) { 48d4afb5ceSopenharmony_ci case LWSSSCS_CREATING: 49d4afb5ceSopenharmony_ci lws_ss_start_timeout(m->ss, 3 * LWS_US_PER_SEC); 50d4afb5ceSopenharmony_ci return lws_ss_request_tx(m->ss); 51d4afb5ceSopenharmony_ci 52d4afb5ceSopenharmony_ci case LWSSSCS_QOS_ACK_REMOTE: 53d4afb5ceSopenharmony_ci lws_system_cpd_set(cx, LWS_CPD_INTERNET_OK); 54d4afb5ceSopenharmony_ci cx->ss_cpd = NULL; 55d4afb5ceSopenharmony_ci return LWSSSSRET_DESTROY_ME; 56d4afb5ceSopenharmony_ci 57d4afb5ceSopenharmony_ci case LWSSSCS_TIMEOUT: 58d4afb5ceSopenharmony_ci case LWSSSCS_ALL_RETRIES_FAILED: 59d4afb5ceSopenharmony_ci case LWSSSCS_DISCONNECTED: 60d4afb5ceSopenharmony_ci /* 61d4afb5ceSopenharmony_ci * First result reported sticks... if nothing else, this will 62d4afb5ceSopenharmony_ci * cover the situation we didn't connect to anything 63d4afb5ceSopenharmony_ci */ 64d4afb5ceSopenharmony_ci lws_system_cpd_set(cx, LWS_CPD_NO_INTERNET); 65d4afb5ceSopenharmony_ci cx->ss_cpd = NULL; 66d4afb5ceSopenharmony_ci return LWSSSSRET_DESTROY_ME; 67d4afb5ceSopenharmony_ci 68d4afb5ceSopenharmony_ci default: 69d4afb5ceSopenharmony_ci break; 70d4afb5ceSopenharmony_ci } 71d4afb5ceSopenharmony_ci 72d4afb5ceSopenharmony_ci return LWSSSSRET_OK; 73d4afb5ceSopenharmony_ci} 74d4afb5ceSopenharmony_ci 75d4afb5ceSopenharmony_cistatic const lws_ss_info_t ssi_cpd = { 76d4afb5ceSopenharmony_ci .handle_offset = offsetof(ss_cpd_t, ss), 77d4afb5ceSopenharmony_ci .opaque_user_data_offset = offsetof(ss_cpd_t, opaque_data), 78d4afb5ceSopenharmony_ci .state = ss_cpd_state, 79d4afb5ceSopenharmony_ci .user_alloc = sizeof(ss_cpd_t), 80d4afb5ceSopenharmony_ci .streamtype = "captive_portal_detect", 81d4afb5ceSopenharmony_ci}; 82d4afb5ceSopenharmony_ci 83d4afb5ceSopenharmony_ciint 84d4afb5ceSopenharmony_cilws_ss_sys_cpd(struct lws_context *cx) 85d4afb5ceSopenharmony_ci{ 86d4afb5ceSopenharmony_ci if (cx->ss_cpd) { 87d4afb5ceSopenharmony_ci lwsl_cx_notice(cx, "CPD already ongoing"); 88d4afb5ceSopenharmony_ci return 0; 89d4afb5ceSopenharmony_ci } 90d4afb5ceSopenharmony_ci 91d4afb5ceSopenharmony_ci if (lws_ss_create(cx, 0, &ssi_cpd, cx, &cx->ss_cpd, NULL, NULL)) { 92d4afb5ceSopenharmony_ci lwsl_cx_info(cx, "Create stream failed (policy?)"); 93d4afb5ceSopenharmony_ci 94d4afb5ceSopenharmony_ci return 1; 95d4afb5ceSopenharmony_ci } 96d4afb5ceSopenharmony_ci 97d4afb5ceSopenharmony_ci return 0; 98d4afb5ceSopenharmony_ci} 99