Compare commits
44 commits
master
...
v2.2-stabl
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fff2bb5b21 | ||
![]() |
12a00ea821 | ||
![]() |
e99d725e76 | ||
![]() |
dc4323f837 | ||
![]() |
ffbefebc24 | ||
![]() |
4cca86926f | ||
![]() |
31b1029234 | ||
![]() |
5a473e0dc3 | ||
![]() |
2e8c0256c0 | ||
![]() |
a64bdff642 | ||
![]() |
a5463053e8 | ||
![]() |
7a8741ec0b | ||
![]() |
fe45fe1860 | ||
![]() |
f6facad476 | ||
![]() |
ccecbb99ab | ||
![]() |
a68539492f | ||
![]() |
36239951be | ||
![]() |
786e6dbf35 | ||
![]() |
2238857ea4 | ||
![]() |
2d6fd20c60 | ||
![]() |
ba16f5172c | ||
![]() |
2977272f0e | ||
![]() |
6da41353ce | ||
![]() |
8d511c834f | ||
![]() |
8e2fe3f12b | ||
![]() |
be333ac420 | ||
![]() |
89ad5714d6 | ||
![]() |
a36ca4dc08 | ||
![]() |
db26ccc38b | ||
![]() |
6f13ccf7c3 | ||
![]() |
f80967b6c1 | ||
![]() |
d2d87776f9 | ||
![]() |
5a354ae44a | ||
![]() |
253ef2180e | ||
![]() |
42ea3bd703 | ||
a7e7d4ea08 | |||
![]() |
b4d2ad04bd | ||
![]() |
f8a995e8d5 | ||
![]() |
dca17ff614 | ||
![]() |
839b1af4e4 | ||
![]() |
906f137794 | ||
![]() |
98eed1871a | ||
![]() |
0be5279eb2 | ||
![]() |
486e72f2cb |
47 changed files with 1463 additions and 201 deletions
|
@ -10,7 +10,7 @@ set(PACKAGE "libwebsockets")
|
|||
set(CPACK_PACKAGE_NAME "${PACKAGE}")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "2")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "2")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "0")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "2")
|
||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
set(CPACK_PACKAGE_VENDOR "andy@warmcat.com")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGE} ${PACKAGE_VERSION}")
|
||||
|
@ -313,19 +313,14 @@ if (LWS_WITH_SQLITE3)
|
|||
endif()
|
||||
|
||||
|
||||
# FIXME: This must be runtime-only option.
|
||||
# The base dir where the test-apps look for the SSL certs.
|
||||
set(LWS_OPENSSL_CLIENT_CERTS ../share CACHE PATH "Server SSL certificate directory")
|
||||
if (WIN32)
|
||||
set(LWS_OPENSSL_CLIENT_CERTS . CACHE PATH "Client SSL certificate directory")
|
||||
|
||||
if (LWS_IPV6)
|
||||
set(LWS_IPV6 OFF)
|
||||
message(WARNING "IPv6 does not currently work on Windows!")
|
||||
endif()
|
||||
if (LWS_UNIX_SOCK)
|
||||
if (LWS_UNIX_SOCK)
|
||||
set(LWS_UNIX_SOCK OFF)
|
||||
message(WARNING "Windows does not support UNIX domain sockets")
|
||||
message(WARNING "Windows does not support UNIX domain sockets")
|
||||
endif()
|
||||
else()
|
||||
set(LWS_OPENSSL_CLIENT_CERTS /etc/pki/tls/certs/ CACHE PATH "Client SSL certificate directory")
|
||||
|
@ -598,7 +593,8 @@ else()
|
|||
else()
|
||||
if (LWS_WITH_ESP32)
|
||||
list(APPEND SOURCES
|
||||
lib/lws-plat-esp32.c)
|
||||
lib/lws-plat-esp32.c
|
||||
lib/romfs.c)
|
||||
else()
|
||||
list(APPEND SOURCES
|
||||
lib/lws-plat-unix.c)
|
||||
|
@ -659,8 +655,12 @@ if (LWS_WITH_RANGES)
|
|||
endif()
|
||||
|
||||
if (LWS_WITH_ZIP_FOPS)
|
||||
list(APPEND SOURCES
|
||||
lib/fops-zip.c)
|
||||
if (LWS_WITH_ZLIB)
|
||||
list(APPEND SOURCES
|
||||
lib/fops-zip.c)
|
||||
else()
|
||||
message(FATAL_ERROR "Pre-zipped file support (LWS_WITH_ZIP_FOPS) requires ZLIB (LWS_WITH_ZLIB)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Add helper files for Windows.
|
||||
|
@ -747,13 +747,13 @@ if (LWS_WITH_STATIC)
|
|||
endif()
|
||||
add_custom_command(
|
||||
TARGET websockets
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/lib/libwebsockets.h
|
||||
${CMAKE_BINARY_DIR}/include/libwebsockets.h
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/lib/libwebsockets.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/libwebsockets.h
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET websockets
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lws_config.h
|
||||
${CMAKE_BINARY_DIR}/include/lws_config.h
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/lws_config.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/lws_config.h
|
||||
)
|
||||
|
||||
endif()
|
||||
|
@ -786,13 +786,13 @@ if (LWS_WITH_SHARED)
|
|||
|
||||
add_custom_command(
|
||||
TARGET websockets_shared
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/lib/libwebsockets.h
|
||||
${CMAKE_BINARY_DIR}/include/libwebsockets.h
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/lib/libwebsockets.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/libwebsockets.h
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET websockets_shared
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lws_config.h
|
||||
${CMAKE_BINARY_DIR}/include/lws_config.h
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/lws_config.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/lws_config.h
|
||||
)
|
||||
|
||||
|
||||
|
@ -989,6 +989,8 @@ set (temp ${CMAKE_REQUIRED_LIBRARIES})
|
|||
set(CMAKE_REQUIRED_LIBRARIES ${LIB_LIST})
|
||||
CHECK_FUNCTION_EXISTS(SSL_CTX_set1_param LWS_HAVE_SSL_CTX_set1_param)
|
||||
CHECK_FUNCTION_EXISTS(X509_VERIFY_PARAM_set1_host LWS_HAVE_X509_VERIFY_PARAM_set1_host)
|
||||
CHECK_FUNCTION_EXISTS(TLS_client_method LWS_HAVE_TLS_CLIENT_METHOD)
|
||||
CHECK_FUNCTION_EXISTS(TLSv1_2_client_method LWS_HAVE_TLSV1_2_CLIENT_METHOD)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${temp})
|
||||
# Generate the lws_config.h that includes all the public compilation settings.
|
||||
configure_file(
|
||||
|
@ -1716,7 +1718,7 @@ message("---------------------------------------------------------------------")
|
|||
# These will be available to parent projects including libwebsockets using add_subdirectory()
|
||||
set(LIBWEBSOCKETS_LIBRARIES ${LWS_LIBRARIES} CACHE STRING "Libwebsocket libraries")
|
||||
if (LWS_WITH_STATIC)
|
||||
set(LIBWEBSOCKETS_LIBRARIES_STATIC websocket CACHE STRING "Libwebsocket static library")
|
||||
set(LIBWEBSOCKETS_LIBRARIES_STATIC websockets CACHE STRING "Libwebsocket static library")
|
||||
endif()
|
||||
if (LWS_WITH_SHARED)
|
||||
set(LIBWEBSOCKETS_LIBRARIES_SHARED websockets_shared CACHE STRING "Libwebsocket shared library")
|
||||
|
|
16
LICENSE
16
LICENSE
|
@ -1,7 +1,13 @@
|
|||
Libwebsockets and included programs are provided under the terms of the GNU
|
||||
Library General Public License (LGPL) 2.1, with the following exceptions:
|
||||
|
||||
1) Static linking of programs with the libwebsockets library does not
|
||||
1) Any reference, whether in these modifications or in the GNU
|
||||
Library General Public License 2.1, to this License, these terms, the
|
||||
GNU Lesser Public License, GNU Library General Public License, LGPL, or
|
||||
any similar reference shall refer to the GNU Library General Public
|
||||
License 2.1 as modified by these paragraphs 1) through 4).
|
||||
|
||||
2) Static linking of programs with the libwebsockets library does not
|
||||
constitute a derivative work and does not require the author to provide
|
||||
source code for the program, use the shared libwebsockets libraries, or
|
||||
link their program against a user-supplied version of libwebsockets.
|
||||
|
@ -10,7 +16,7 @@ If you link the program to a modified version of libwebsockets, then the
|
|||
changes to libwebsockets must be provided under the terms of the LGPL in
|
||||
sections 1, 2, and 4.
|
||||
|
||||
2) You do not have to provide a copy of the libwebsockets license with
|
||||
3) You do not have to provide a copy of the libwebsockets license with
|
||||
programs that are linked to the libwebsockets library, nor do you have to
|
||||
identify the libwebsockets license in your program or documentation as
|
||||
required by section 6 of the LGPL.
|
||||
|
@ -22,7 +28,7 @@ satisfy this requirement:
|
|||
"[program] is based in part on the work of the libwebsockets project
|
||||
(https://libwebsockets.org)"
|
||||
|
||||
3) Some sources included have their own, more liberal licenses, or options
|
||||
4) Some sources included have their own, more liberal licenses, or options
|
||||
to get original sources with the liberal terms.
|
||||
|
||||
Original liberal license retained
|
||||
|
@ -41,7 +47,9 @@ Public Domain (CC-zero) to simplify reuse
|
|||
- test-server/*.c
|
||||
- test-server/*.h
|
||||
- lwsws/*
|
||||
|
||||
|
||||
------ end of exceptions
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ cmake from scratch.
|
|||
|
||||
2. Fix up MinGW headers
|
||||
|
||||
a) Add the following lines to C:\MinGW\include\winsock2.h:
|
||||
a) (32-bit) Add the following lines to C:\MinGW\include\winsock2.h:
|
||||
```
|
||||
#if(_WIN32_WINNT >= 0x0600)
|
||||
|
||||
|
@ -192,9 +192,17 @@ cmake from scratch.
|
|||
|
||||
#endif // (_WIN32_WINNT >= 0x0600)
|
||||
```
|
||||
|
||||
(64 bit) Update crtdefs.h line 47 to say:
|
||||
|
||||
```
|
||||
typedef __int64 ssize_t;
|
||||
```
|
||||
|
||||
b) Create C:\MinGW\include\mstcpip.h and copy and paste the content from following link into it:
|
||||
|
||||
http://wine-unstable.sourcearchive.com/documentation/1.1.32/mstcpip_8h-source.html
|
||||
(32-bit) http://wine-unstable.sourcearchive.com/documentation/1.1.32/mstcpip_8h-source.html
|
||||
(64-bit) https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-headers/include/mstcpip.h
|
||||
|
||||
3. Install CMake 2.6 or greater: http://cmake.org/cmake/resources/software.html
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ build:
|
|||
cmake $(COMPONENT_PATH) -DLWS_C_FLAGS="$(CFLAGS)" \
|
||||
-DCROSS_PATH=$(CROSS_PATH) \
|
||||
-DCOMPONENT_PATH=$(COMPONENT_PATH) \
|
||||
-DBUILD_DIR_BASE=$(BUILD_DIR_BASE) \
|
||||
-DCMAKE_TOOLCHAIN_FILE=$(COMPONENT_PATH)/cross-esp32.cmake \
|
||||
-DCMAKE_BUILD_TYPE=RELEASE \
|
||||
-DLWS_WITH_NO_LOGS=0 \
|
||||
|
|
|
@ -12,7 +12,7 @@ set(CMAKE_SYSTEM_NAME Linux)
|
|||
# Name of C compiler.
|
||||
set(CMAKE_C_COMPILER "${CROSS_PATH}/bin/xtensa-esp32-elf-gcc")
|
||||
|
||||
SET(CMAKE_C_FLAGS "-nostdlib -Wall -Werror -I${COMPONENT_PATH}/../lwip/include/lwip/posix -I${COMPONENT_PATH}/../lwip/include/lwip -I${COMPONENT_PATH}/../lwip/include/lwip/port -I${COMPONENT_PATH}/../esp32/include/ ${LWS_C_FLAGS} -I${COMPONENT_PATH}/../nvs_flash/test_nvs_host -I${COMPONENT_PATH}/../freertos/include -Os" CACHE STRING "" FORCE)
|
||||
SET(CMAKE_C_FLAGS "-nostdlib -Wall -Werror -I${BUILD_DIR_BASE}/include -I${COMPONENT_PATH}/../driver/include -I${COMPONENT_PATH}/../spi_flash/include -I${COMPONENT_PATH}/../nvs_flash/include -I${COMPONENT_PATH}/../tcpip_adapter/include -I${COMPONENT_PATH}/../lwip/include/lwip/posix -I${COMPONENT_PATH}/../lwip/include/lwip -I${COMPONENT_PATH}/../lwip/include/lwip/port -I${COMPONENT_PATH}/../esp32/include/ ${LWS_C_FLAGS} -I${COMPONENT_PATH}/../nvs_flash/test_nvs_host -I${COMPONENT_PATH}/../freertos/include -Os" CACHE STRING "" FORCE)
|
||||
|
||||
# Where to look for the target environment. (More paths can be added here)
|
||||
set(CMAKE_FIND_ROOT_PATH "${CROSS_PATH}")
|
||||
|
|
|
@ -101,6 +101,8 @@ lws_client_connect_2(struct lws *wsi)
|
|||
memcpy(&server_addr6.sin6_addr,
|
||||
&((struct sockaddr_in6 *)result->ai_addr)->sin6_addr,
|
||||
sizeof(struct in6_addr));
|
||||
server_addr6.sin6_scope_id = ((struct sockaddr_in6 *)result->ai_addr)->sin6_scope_id;
|
||||
server_addr6.sin6_flowinfo = ((struct sockaddr_in6 *)result->ai_addr)->sin6_flowinfo;
|
||||
break;
|
||||
default:
|
||||
lwsl_err("Unknown address family\n");
|
||||
|
|
|
@ -21,9 +21,13 @@
|
|||
|
||||
#include "private-libwebsockets.h"
|
||||
|
||||
/*
|
||||
* parsers.c: lws_rx_sm() needs to be roughly kept in
|
||||
* sync with changes here, esp related to ext draining
|
||||
*/
|
||||
|
||||
int lws_client_rx_sm(struct lws *wsi, unsigned char c)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
|
||||
int callback_action = LWS_CALLBACK_CLIENT_RECEIVE;
|
||||
int handled, n, m, rx_draining_ext = 0;
|
||||
unsigned short close_code;
|
||||
|
@ -31,26 +35,19 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c)
|
|||
unsigned char *pp;
|
||||
|
||||
if (wsi->u.ws.rx_draining_ext) {
|
||||
struct lws **w = &pt->rx_draining_ext_list;
|
||||
lwsl_ext("%s: RX EXT DRAINING: Removing from list\n", __func__);
|
||||
assert(!c);
|
||||
eff_buf.token = NULL;
|
||||
eff_buf.token_len = 0;
|
||||
wsi->u.ws.rx_draining_ext = 0;
|
||||
/* remove us from context draining ext list */
|
||||
while (*w) {
|
||||
if (*w == wsi) {
|
||||
*w = wsi->u.ws.rx_draining_ext_list;
|
||||
break;
|
||||
}
|
||||
w = &((*w)->u.ws.rx_draining_ext_list);
|
||||
}
|
||||
wsi->u.ws.rx_draining_ext_list = NULL;
|
||||
lws_remove_wsi_from_draining_ext_list(wsi);
|
||||
rx_draining_ext = 1;
|
||||
lwsl_debug("%s: doing draining flow\n", __func__);
|
||||
|
||||
goto drain_extension;
|
||||
}
|
||||
|
||||
if (wsi->socket_is_permanently_unusable)
|
||||
return -1;
|
||||
|
||||
switch (wsi->lws_rx_parse_state) {
|
||||
case LWS_RXPS_NEW:
|
||||
/* control frames (PING) may interrupt checkable sequences */
|
||||
|
@ -308,6 +305,9 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c)
|
|||
|
||||
assert(wsi->u.ws.rx_ubuf);
|
||||
|
||||
if (wsi->u.ws.rx_draining_ext)
|
||||
goto drain_extension;
|
||||
|
||||
if (wsi->u.ws.this_frame_masked && !wsi->u.ws.all_zero_nonce)
|
||||
c ^= wsi->u.ws.mask[(wsi->u.ws.mask_idx++) & 3];
|
||||
|
||||
|
@ -365,10 +365,14 @@ spill:
|
|||
wsi->u.ws.rx_ubuf_head);
|
||||
if (wsi->u.ws.rx_ubuf_head >= 2) {
|
||||
close_code = (pp[0] << 8) | pp[1];
|
||||
if (close_code < 1000 || close_code == 1004 ||
|
||||
close_code == 1005 || close_code == 1006 ||
|
||||
close_code == 1012 || close_code == 1013 ||
|
||||
close_code == 1014 || close_code == 1015 ||
|
||||
if (close_code < 1000 ||
|
||||
close_code == 1004 ||
|
||||
close_code == 1005 ||
|
||||
close_code == 1006 ||
|
||||
close_code == 1012 ||
|
||||
close_code == 1013 ||
|
||||
close_code == 1014 ||
|
||||
close_code == 1015 ||
|
||||
(close_code >= 1016 && close_code < 3000)
|
||||
) {
|
||||
pp[0] = (LWS_CLOSE_STATUS_PROTOCOL_ERR >> 8) & 0xff;
|
||||
|
@ -381,6 +385,7 @@ spill:
|
|||
wsi->user_space, pp,
|
||||
wsi->u.ws.rx_ubuf_head))
|
||||
return -1;
|
||||
|
||||
if (lws_partial_buffered(wsi))
|
||||
/*
|
||||
* if we're in the middle of something,
|
||||
|
@ -496,10 +501,14 @@ ping_drop:
|
|||
eff_buf.token_len = wsi->u.ws.rx_ubuf_head;
|
||||
|
||||
drain_extension:
|
||||
lwsl_ext("%s: passing %d to ext\n", __func__, eff_buf.token_len);
|
||||
|
||||
n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &eff_buf, 0);
|
||||
lwsl_ext("Ext RX returned %d\n", n);
|
||||
if (n < 0) /* fail */
|
||||
if (n < 0) {
|
||||
wsi->socket_is_permanently_unusable = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lwsl_ext("post inflate eff_buf len %d\n", eff_buf.token_len);
|
||||
|
||||
|
@ -515,7 +524,8 @@ drain_extension:
|
|||
goto utf8_fail;
|
||||
|
||||
/* we are ending partway through utf-8 character? */
|
||||
if (!wsi->u.ws.rx_packet_length && wsi->u.ws.final && wsi->u.ws.utf8 && !n) {
|
||||
if (!wsi->u.ws.rx_packet_length && wsi->u.ws.final &&
|
||||
wsi->u.ws.utf8 && !n) {
|
||||
lwsl_info("FINAL utf8 error\n");
|
||||
utf8_fail: lwsl_info("utf8 error\n");
|
||||
return -1;
|
||||
|
@ -537,17 +547,16 @@ utf8_fail: lwsl_info("utf8 error\n");
|
|||
if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG)
|
||||
lwsl_info("Client doing pong callback\n");
|
||||
|
||||
if (n && eff_buf.token_len) {
|
||||
if (n && eff_buf.token_len)
|
||||
/* extension had more... main loop will come back
|
||||
* we want callback to be done with this set, if so,
|
||||
* because lws_is_final() hides it was final until the
|
||||
* last chunk
|
||||
*/
|
||||
wsi->u.ws.rx_draining_ext = 1;
|
||||
wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list;
|
||||
pt->rx_draining_ext_list = wsi;
|
||||
lwsl_ext("%s: RX EXT DRAINING: Adding to list\n", __func__);
|
||||
}
|
||||
lws_add_wsi_to_draining_ext_list(wsi);
|
||||
else
|
||||
lws_remove_wsi_from_draining_ext_list(wsi);
|
||||
|
||||
if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY ||
|
||||
wsi->state == LWSS_AWAITING_CLOSE_ACK)
|
||||
goto already_done;
|
||||
|
|
|
@ -426,10 +426,10 @@ lws_client_interpret_server_handshake(struct lws *wsi)
|
|||
void *v;
|
||||
#endif
|
||||
|
||||
ah = wsi->u.hdr.ah;
|
||||
if (!wsi->do_ws) {
|
||||
/* we are being an http client...
|
||||
*/
|
||||
ah = wsi->u.hdr.ah;
|
||||
lws_union_transition(wsi, LWSCM_HTTP_CLIENT_ACCEPTED);
|
||||
wsi->state = LWSS_CLIENT_HTTP_ESTABLISHED;
|
||||
wsi->u.http.ah = ah;
|
||||
|
|
|
@ -40,6 +40,7 @@ lws_get_library_version(void)
|
|||
return library_version;
|
||||
}
|
||||
|
||||
#if !defined(LWS_WITH_NO_LOGS)
|
||||
static const char * const mount_protocols[] = {
|
||||
"http://",
|
||||
"https://",
|
||||
|
@ -49,6 +50,7 @@ static const char * const mount_protocols[] = {
|
|||
">https://",
|
||||
"callback://"
|
||||
};
|
||||
#endif
|
||||
|
||||
LWS_VISIBLE void *
|
||||
lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_protocols *prot,
|
||||
|
@ -419,7 +421,7 @@ lws_create_vhost(struct lws_context *context,
|
|||
vh->protocols = lwsp;
|
||||
else {
|
||||
vh->protocols = info->protocols;
|
||||
free(lwsp);
|
||||
lws_free(lwsp);
|
||||
}
|
||||
|
||||
vh->same_vh_protocol_list = (struct lws **)
|
||||
|
|
|
@ -202,7 +202,7 @@ lws_extension_callback_pm_deflate(struct lws_context *context,
|
|||
* rx buffer by the caller, so this assumption is safe while
|
||||
* we block new rx while draining the existing rx
|
||||
*/
|
||||
if (eff_buf->token && eff_buf->token_len) {
|
||||
if (!priv->rx.avail_in && eff_buf->token && eff_buf->token_len) {
|
||||
priv->rx.next_in = (unsigned char *)eff_buf->token;
|
||||
priv->rx.avail_in = eff_buf->token_len;
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@ lws_fops_zip_scan(lws_fops_zip_t priv, const char *name, int len)
|
|||
if (get_u32(buf + ZC_SIGNATURE) != 0x02014B50)
|
||||
return LWS_FZ_ERR_CENTRAL_SANITY;
|
||||
|
||||
lwsl_debug("cstart 0x%lx\n", priv->content_start);
|
||||
lwsl_debug("cstart 0x%lx\n", (unsigned long)priv->content_start);
|
||||
|
||||
priv->hdr.filename_len = get_u16(buf + ZC_FILE_NAME_LENGTH);
|
||||
priv->hdr.extra = get_u16(buf + ZC_EXTRA_FIELD_LENGTH);
|
||||
|
@ -272,7 +272,7 @@ lws_fops_zip_scan(lws_fops_zip_t priv, const char *name, int len)
|
|||
get_u16(buf + ZL_REL_OFFSET_CONTENT);
|
||||
|
||||
lwsl_debug("content supposed to start at 0x%lx\n",
|
||||
priv->content_start);
|
||||
(unsigned long)priv->content_start);
|
||||
|
||||
if (priv->content_start > priv->zip_fop_fd->len)
|
||||
return LWS_FZ_ERR_CONTENT_SANITY;
|
||||
|
|
|
@ -169,7 +169,7 @@ int lws_http2_frame_write(struct lws *wsi, int type, int flags,
|
|||
*p++ = sid >> 8;
|
||||
*p++ = sid;
|
||||
|
||||
lwsl_info("%s: %p (eff %p). type %d, flags 0x%x, sid=%d, len=%d\n",
|
||||
lwsl_info("%s: %p (eff %p). type %d, flags 0x%x, sid=%d, len=%d, tx_credit=%d\n",
|
||||
__func__, wsi, wsi_eff, type, flags, sid, len,
|
||||
wsi->u.http2.tx_credit);
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ lws_libev_io(struct lws *wsi, int flags)
|
|||
if (!LWS_LIBEV_ENABLED(context))
|
||||
return;
|
||||
|
||||
if (!pt->io_loop_ev || context->being_destroyed)
|
||||
if (!pt->io_loop_ev)
|
||||
return;
|
||||
|
||||
assert((flags & (LWS_EV_START | LWS_EV_STOP)) &&
|
||||
|
|
36
lib/libuv.c
36
lib/libuv.c
|
@ -40,7 +40,7 @@ lws_uv_idle(uv_idle_t *handle
|
|||
struct lws_context_per_thread *pt = lws_container_of(handle,
|
||||
struct lws_context_per_thread, uv_idle);
|
||||
|
||||
lwsl_debug("%s\n", __func__);
|
||||
// lwsl_debug("%s\n", __func__);
|
||||
|
||||
/*
|
||||
* is there anybody with pending stuff that needs service forcing?
|
||||
|
@ -51,7 +51,7 @@ lws_uv_idle(uv_idle_t *handle
|
|||
/* still somebody left who wants forced service? */
|
||||
if (!lws_service_adjust_timeout(pt->context, 1, pt->tid))
|
||||
/* yes... come back again later */
|
||||
lwsl_debug("%s: done again\n", __func__);
|
||||
// lwsl_debug("%s: done again\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,8 @@ static void lws_uv_close_cb(uv_handle_t *handle)
|
|||
|
||||
static void lws_uv_walk_cb(uv_handle_t *handle, void *arg)
|
||||
{
|
||||
uv_close(handle, lws_uv_close_cb);
|
||||
if (!uv_is_closing(handle))
|
||||
uv_close(handle, lws_uv_close_cb);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -331,7 +332,7 @@ lws_libuv_accept(struct lws *wsi, lws_sock_file_fd_type desc)
|
|||
wsi->w_read.context = context;
|
||||
if (wsi->mode == LWSCM_RAW_FILEDESC)
|
||||
uv_poll_init(pt->io_loop_uv, &wsi->w_read.uv_watcher,
|
||||
desc.filefd);
|
||||
(int)desc.filefd);
|
||||
else
|
||||
uv_poll_init_socket(pt->io_loop_uv, &wsi->w_read.uv_watcher,
|
||||
desc.sockfd);
|
||||
|
@ -541,6 +542,11 @@ lws_plat_plugins_init(struct lws_context *context, const char * const *d)
|
|||
char path[256];
|
||||
uv_loop_t loop;
|
||||
uv_lib_t lib;
|
||||
int pofs = 0;
|
||||
|
||||
#if defined(__MINGW32__) || !defined(WIN32)
|
||||
pofs = 3;
|
||||
#endif
|
||||
|
||||
lib.errmsg = NULL;
|
||||
lib.handle = NULL;
|
||||
|
@ -570,19 +576,20 @@ lws_plat_plugins_init(struct lws_context *context, const char * const *d)
|
|||
lwsl_err("Error loading DSO: %s\n", lib.errmsg);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* we could open it, can we get his init function? */
|
||||
#if !defined(WIN32)
|
||||
#if !defined(WIN32) && !defined(__MINGW32__)
|
||||
m = lws_snprintf(path, sizeof(path) - 1, "init_%s",
|
||||
dent.name + 3 /* snip lib... */);
|
||||
dent.name + pofs /* snip lib... */);
|
||||
path[m - 3] = '\0'; /* snip the .so */
|
||||
#else
|
||||
m = lws_snprintf(path, sizeof(path) - 1, "init_%s",
|
||||
dent.name);
|
||||
dent.name + pofs);
|
||||
path[m - 4] = '\0'; /* snip the .dll */
|
||||
#endif
|
||||
if (uv_dlsym(&lib, path, &v)) {
|
||||
uv_dlerror(&lib);
|
||||
lwsl_err("Failed to get init on %s: %s",
|
||||
lwsl_err("Failed to get %s on %s: %s", path,
|
||||
dent.name, lib.errmsg);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -633,6 +640,11 @@ lws_plat_plugins_destroy(struct lws_context *context)
|
|||
char path[256];
|
||||
void *v;
|
||||
int m;
|
||||
int pofs = 0;
|
||||
|
||||
#if defined(__MINGW32__) || !defined(WIN32)
|
||||
pofs = 3;
|
||||
#endif
|
||||
|
||||
if (!plugin)
|
||||
return 0;
|
||||
|
@ -641,17 +653,17 @@ lws_plat_plugins_destroy(struct lws_context *context)
|
|||
|
||||
while (plugin) {
|
||||
p = plugin;
|
||||
#if !defined(WIN32)
|
||||
m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name + 3);
|
||||
#if !defined(WIN32) && !defined(__MINGW32__)
|
||||
m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name + pofs);
|
||||
path[m - 3] = '\0';
|
||||
#else
|
||||
m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name);
|
||||
m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name + pofs);
|
||||
path[m - 4] = '\0';
|
||||
#endif
|
||||
|
||||
if (uv_dlsym(&plugin->lib, path, &v)) {
|
||||
uv_dlerror(&plugin->lib);
|
||||
lwsl_err("Failed to get init on %s: %s",
|
||||
lwsl_err("Failed to get %s on %s: %s", path,
|
||||
plugin->name, plugin->lib.errmsg);
|
||||
} else {
|
||||
func = (lws_plugin_destroy_func)v;
|
||||
|
|
|
@ -480,13 +480,28 @@ just_kill_connection:
|
|||
!wsi->socket_is_permanently_unusable) {
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
if (lws_is_ssl(wsi) && wsi->ssl)
|
||||
{
|
||||
lwsl_info("%s: shutting down SSL connection: %p (ssl %p, sock %d, state %d)\n", __func__, wsi, wsi->ssl, (int)(long)wsi->desc.sockfd, wsi->state);
|
||||
{
|
||||
lwsl_info("%s: shutting down SSL connection: %p (ssl %p, sock %d, state %d)\n", __func__, wsi, wsi->ssl, (int)(long)wsi->desc.sockfd, wsi->state);
|
||||
n = SSL_shutdown(wsi->ssl);
|
||||
if (n == 0) /* Complete bidirectional SSL shutdown */
|
||||
SSL_shutdown(wsi->ssl);
|
||||
n = shutdown(wsi->desc.sockfd, SHUT_WR);
|
||||
}
|
||||
if (n == 1) /* If finished the SSL shutdown, then do socket shutdown, else need to retry SSL shutdown */
|
||||
n = shutdown(wsi->desc.sockfd, SHUT_WR);
|
||||
else if (n == 0)
|
||||
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
|
||||
else /* n < 0 */
|
||||
{
|
||||
int shutdown_error = SSL_get_error(wsi->ssl, n);
|
||||
lwsl_debug("SSL_shutdown returned %d, SSL_get_error: %d\n", n, shutdown_error);
|
||||
if (shutdown_error == SSL_ERROR_WANT_READ) {
|
||||
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
|
||||
n = 0;
|
||||
} else if (shutdown_error == SSL_ERROR_WANT_WRITE) {
|
||||
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLOUT);
|
||||
n = 0;
|
||||
} else { // actual error occurred, just close the connection
|
||||
n = shutdown(wsi->desc.sockfd, SHUT_WR);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
@ -1754,10 +1769,10 @@ lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
|
|||
#endif
|
||||
struct sockaddr_in serv_addr4;
|
||||
#ifndef LWS_PLAT_OPTEE
|
||||
socklen_t len = sizeof(struct sockaddr);
|
||||
socklen_t len = sizeof(struct sockaddr_storage);
|
||||
#endif
|
||||
int n;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_storage sin;
|
||||
struct sockaddr *v;
|
||||
|
||||
#ifdef LWS_USE_UNIX_SOCK
|
||||
|
@ -1789,6 +1804,7 @@ lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
if (iface) {
|
||||
struct ifaddrs *addrs, *addr;
|
||||
char ip[NI_MAXHOST];
|
||||
|
@ -1820,6 +1836,7 @@ lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
|
|||
}
|
||||
freeifaddrs(addrs);
|
||||
}
|
||||
#endif
|
||||
|
||||
serv_addr6.sin6_family = AF_INET6;
|
||||
serv_addr6.sin6_port = htons(port);
|
||||
|
@ -1862,7 +1879,13 @@ lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
|
|||
lwsl_warn("getsockname: %s\n", strerror(LWS_ERRNO));
|
||||
else
|
||||
#endif
|
||||
port = ntohs(sin.sin_port);
|
||||
#if defined(LWS_USE_IPV6)
|
||||
port = (sin.ss_family == AF_INET6) ?
|
||||
ntohs(((struct sockaddr_in6 *) &sin)->sin6_port) :
|
||||
ntohs(((struct sockaddr_in *) &sin)->sin_port);
|
||||
#else
|
||||
port = ntohs(((struct sockaddr_in *) &sin)->sin_port);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return port;
|
||||
|
|
|
@ -33,12 +33,6 @@ extern "C" {
|
|||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
static inline int lws_is_be(void) {
|
||||
const int probe = ~0xff;
|
||||
|
||||
return *(const char *)&probe;
|
||||
}
|
||||
|
||||
#if defined(LWS_WITH_ESP8266)
|
||||
struct sockaddr_in;
|
||||
#define LWS_POSIX 0
|
||||
|
@ -99,6 +93,10 @@ struct sockaddr_in;
|
|||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
#if !defined(__MINGW32__) &&(!defined(_MSC_VER) || _MSC_VER < 1900) && !defined(snprintf)
|
||||
#define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#else /* NOT WIN32 */
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -292,6 +290,12 @@ LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len);
|
|||
|
||||
#endif
|
||||
|
||||
static LWS_INLINE int lws_is_be(void) {
|
||||
const int probe = ~0xff;
|
||||
|
||||
return *(const char *)&probe;
|
||||
}
|
||||
|
||||
/**
|
||||
* lws_set_log_level() - Set the logging bitfield
|
||||
* \param level: OR together the LLL_ debug contexts you want output from
|
||||
|
@ -460,6 +464,16 @@ struct pollfd {
|
|||
#define POLLHUP 0x0010
|
||||
#define POLLNVAL 0x0020
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/event_groups.h>
|
||||
#include <string.h>
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_event_loop.h"
|
||||
#include "nvs.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "freertos/timers.h"
|
||||
|
||||
#if !defined(CONFIG_FREERTOS_HZ)
|
||||
|
@ -513,8 +527,35 @@ static inline void uv_close(uv_handle_t *h, void *v)
|
|||
xTimerDelete(*(uv_timer_t *)h, 0);
|
||||
}
|
||||
|
||||
/* ESP32 helper declarations */
|
||||
|
||||
#define LWS_PLUGIN_STATIC
|
||||
|
||||
/* user code provides these */
|
||||
|
||||
extern char lws_esp32_model[16];
|
||||
|
||||
extern int
|
||||
lws_esp32_is_booting_in_ap_mode(void);
|
||||
extern void
|
||||
lws_esp32_identify_physical_device(void);
|
||||
|
||||
/* lws-plat-esp32 provides these */
|
||||
|
||||
extern void (*lws_cb_scan_done)(void *);
|
||||
extern void *lws_cb_scan_done_arg;
|
||||
|
||||
extern char lws_esp32_serial[], lws_esp32_force_ap, lws_esp32_region;
|
||||
|
||||
extern esp_err_t
|
||||
lws_esp32_event_passthru(void *ctx, system_event_t *event);
|
||||
extern void
|
||||
lws_esp32_wlan_config(void);
|
||||
extern void
|
||||
lws_esp32_wlan_start(void);
|
||||
struct lws_context_creation_info;
|
||||
extern struct lws_context *
|
||||
lws_esp32_init(struct lws_context_creation_info *, unsigned int _romfs);
|
||||
|
||||
#else
|
||||
typedef int lws_sockfd_type;
|
||||
|
@ -3527,7 +3568,7 @@ lws_callback_on_writable(struct lws *wsi);
|
|||
|
||||
/**
|
||||
* lws_callback_on_writable_all_protocol() - Request a callback for all
|
||||
* connections on same vhost using the given protocol when it
|
||||
* connections using the given protocol when it
|
||||
* becomes possible to write to each socket without
|
||||
* blocking in turn.
|
||||
*
|
||||
|
@ -3544,8 +3585,8 @@ lws_callback_on_writable_all_protocol(const struct lws_context *context,
|
|||
|
||||
/**
|
||||
* lws_callback_on_writable_all_protocol_vhost() - Request a callback for
|
||||
* all connections using the given protocol when it
|
||||
* becomes possible to write to each socket without
|
||||
* all connections on same vhost using the given protocol
|
||||
* when it becomes possible to write to each socket without
|
||||
* blocking in turn.
|
||||
*
|
||||
* \param vhost: Only consider connections on this lws_vhost
|
||||
|
@ -3568,8 +3609,12 @@ lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost,
|
|||
* \param reason: Callback reason index
|
||||
*
|
||||
* - Which: connections using this protocol on ALL VHOSTS
|
||||
* - When: when the individual connection becomes writeable
|
||||
* - When: before returning
|
||||
* - What: reason
|
||||
*
|
||||
* This isn't normally what you want... normally any update of connection-
|
||||
* specific information can wait until a network-related callback like rx,
|
||||
* writable, or close.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_callback_all_protocol(struct lws_context *context,
|
||||
|
@ -4296,7 +4341,7 @@ lws_cgi_kill(struct lws *wsi);
|
|||
|
||||
struct lws_plat_file_ops;
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#if (defined(WIN32) || defined(_WIN32)) && !defined(__MINGW32__)
|
||||
/* ... */
|
||||
#if !defined(ssize_t)
|
||||
typedef SSIZE_T ssize_t;
|
||||
|
@ -4428,7 +4473,7 @@ lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset);
|
|||
LWS_VISIBLE LWS_EXTERN lws_fileofs_t
|
||||
lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops fops_zip;
|
||||
extern struct lws_plat_file_ops fops_zip;
|
||||
|
||||
/**
|
||||
* lws_plat_file_open() - open vfs filepath
|
||||
|
|
|
@ -528,3 +528,277 @@ char *ERR_error_string(unsigned long e, char *buf)
|
|||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
|
||||
/* helper functionality */
|
||||
|
||||
#include "romfs.h"
|
||||
|
||||
void (*lws_cb_scan_done)(void *);
|
||||
void *lws_cb_scan_done_arg;
|
||||
char lws_esp32_serial[16] = "unknown", lws_esp32_force_ap = 0,
|
||||
lws_esp32_region = WIFI_COUNTRY_US; // default to safest option
|
||||
|
||||
static romfs_t lws_esp32_romfs;
|
||||
|
||||
/*
|
||||
* configuration related to the AP setup website
|
||||
*
|
||||
* The 'esplws-scan' protocol drives the configuration
|
||||
* site, and updates the scan results in realtime over
|
||||
* a websocket link.
|
||||
*/
|
||||
|
||||
#include "../plugins/protocol_esp32_lws_scan.c"
|
||||
|
||||
static const struct lws_protocols protocols_ap[] = {
|
||||
{
|
||||
"http-only",
|
||||
lws_callback_http_dummy,
|
||||
0, /* per_session_data_size */
|
||||
900, 0, NULL
|
||||
},
|
||||
LWS_PLUGIN_PROTOCOL_ESPLWS_SCAN,
|
||||
{ NULL, NULL, 0, 0, 0, NULL } /* terminator */
|
||||
};
|
||||
|
||||
static const struct lws_protocol_vhost_options ap_pvo = {
|
||||
NULL,
|
||||
NULL,
|
||||
"esplws-scan",
|
||||
""
|
||||
};
|
||||
|
||||
static const struct lws_http_mount mount_ap = {
|
||||
.mountpoint = "/",
|
||||
.origin = "/ap",
|
||||
.def = "index.html",
|
||||
.origin_protocol = LWSMPRO_FILE,
|
||||
.mountpoint_len = 1,
|
||||
};
|
||||
|
||||
struct esp32_file {
|
||||
const struct inode *i;
|
||||
};
|
||||
|
||||
esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event)
|
||||
{
|
||||
switch(event->event_id) {
|
||||
case SYSTEM_EVENT_SCAN_DONE:
|
||||
if (lws_cb_scan_done)
|
||||
lws_cb_scan_done(lws_cb_scan_done_arg);
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_START:
|
||||
esp_wifi_connect();
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||
/* This is a workaround as ESP32 WiFi libs don't currently
|
||||
auto-reassociate. */
|
||||
esp_wifi_connect();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static lws_fop_fd_t IRAM_ATTR
|
||||
esp32_lws_fops_open(const struct lws_plat_file_ops *fops, const char *filename,
|
||||
const char *vfs_path, lws_fop_flags_t *flags)
|
||||
{
|
||||
struct esp32_file *f = malloc(sizeof(*f));
|
||||
lws_fop_fd_t fop_fd;
|
||||
size_t len;
|
||||
|
||||
lwsl_notice("%s: %s\n", __func__, filename);
|
||||
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
f->i = romfs_get_info(lws_esp32_romfs, filename, &len);
|
||||
if (!f->i)
|
||||
goto bail;
|
||||
|
||||
fop_fd = malloc(sizeof(*fop_fd));
|
||||
if (!fop_fd)
|
||||
goto bail;
|
||||
|
||||
fop_fd->fops = fops;
|
||||
fop_fd->filesystem_priv = f;
|
||||
fop_fd->flags = *flags;
|
||||
|
||||
fop_fd->len = len;
|
||||
fop_fd->pos = 0;
|
||||
|
||||
return fop_fd;
|
||||
|
||||
bail:
|
||||
free(f);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int IRAM_ATTR
|
||||
esp32_lws_fops_close(lws_fop_fd_t *fop_fd)
|
||||
{
|
||||
free((*fop_fd)->filesystem_priv);
|
||||
free(*fop_fd);
|
||||
|
||||
*fop_fd = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static lws_fileofs_t IRAM_ATTR
|
||||
esp32_lws_fops_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset_from_cur_pos)
|
||||
{
|
||||
fop_fd->pos += offset_from_cur_pos;
|
||||
|
||||
if (fop_fd->pos > fop_fd->len)
|
||||
fop_fd->pos = fop_fd->len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int IRAM_ATTR
|
||||
esp32_lws_fops_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, uint8_t *buf,
|
||||
lws_filepos_t len)
|
||||
{
|
||||
struct esp32_file *f = fop_fd->filesystem_priv;
|
||||
|
||||
if ((long)buf & 3) {
|
||||
lwsl_err("misaligned buf\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fop_fd->pos >= fop_fd->len)
|
||||
return 0;
|
||||
|
||||
if (len > fop_fd->len - fop_fd->pos)
|
||||
len = fop_fd->len - fop_fd->pos;
|
||||
|
||||
spi_flash_read((uint32_t)(char *)f->i + fop_fd->pos, buf, len);
|
||||
|
||||
*amount = len;
|
||||
fop_fd->pos += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct lws_plat_file_ops fops = {
|
||||
.LWS_FOP_OPEN = esp32_lws_fops_open,
|
||||
.LWS_FOP_CLOSE = esp32_lws_fops_close,
|
||||
.LWS_FOP_READ = esp32_lws_fops_read,
|
||||
.LWS_FOP_SEEK_CUR = esp32_lws_fops_seek_cur,
|
||||
};
|
||||
|
||||
static wifi_config_t sta_config = {
|
||||
.sta = {
|
||||
.bssid_set = false
|
||||
}
|
||||
}, ap_config = {
|
||||
.ap = {
|
||||
.channel = 6,
|
||||
.authmode = WIFI_AUTH_OPEN,
|
||||
.max_connection = 1,
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
lws_esp32_wlan_config(void)
|
||||
{
|
||||
nvs_handle nvh;
|
||||
char r[2];
|
||||
size_t s;
|
||||
|
||||
ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh));
|
||||
|
||||
s = sizeof(sta_config.sta.ssid) - 1;
|
||||
if (nvs_get_str(nvh, "ssid", (char *)sta_config.sta.ssid, &s) != ESP_OK)
|
||||
lws_esp32_force_ap = 1;
|
||||
s = sizeof(sta_config.sta.password) - 1;
|
||||
if (nvs_get_str(nvh, "password", (char *)sta_config.sta.password, &s) != ESP_OK)
|
||||
lws_esp32_force_ap = 1;
|
||||
s = sizeof(lws_esp32_serial) - 1;
|
||||
if (nvs_get_str(nvh, "serial", lws_esp32_serial, &s) != ESP_OK)
|
||||
lws_esp32_force_ap = 1;
|
||||
else
|
||||
snprintf((char *)ap_config.ap.ssid, sizeof(ap_config.ap.ssid) - 1,
|
||||
"config-%s-%s", lws_esp32_model, lws_esp32_serial);
|
||||
s = sizeof(r);
|
||||
if (nvs_get_str(nvh, "region", r, &s) != ESP_OK)
|
||||
lws_esp32_force_ap = 1;
|
||||
else
|
||||
lws_esp32_region = atoi(r);
|
||||
|
||||
nvs_close(nvh);
|
||||
|
||||
tcpip_adapter_init();
|
||||
}
|
||||
|
||||
void
|
||||
lws_esp32_wlan_start(void)
|
||||
{
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
|
||||
ESP_ERROR_CHECK( esp_wifi_init(&cfg));
|
||||
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM));
|
||||
ESP_ERROR_CHECK( esp_wifi_set_country(lws_esp32_region));
|
||||
|
||||
if (!lws_esp32_is_booting_in_ap_mode() && !lws_esp32_force_ap) {
|
||||
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config));
|
||||
} else {
|
||||
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_APSTA) );
|
||||
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_AP, &ap_config) );
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK( esp_wifi_start());
|
||||
tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, (const char *)&ap_config.ap.ssid[7]);
|
||||
|
||||
if (!lws_esp32_is_booting_in_ap_mode() && !lws_esp32_force_ap)
|
||||
ESP_ERROR_CHECK( esp_wifi_connect());
|
||||
}
|
||||
|
||||
struct lws_context *
|
||||
lws_esp32_init(struct lws_context_creation_info *info, unsigned int _romfs)
|
||||
{
|
||||
size_t romfs_size;
|
||||
struct lws_context *context;
|
||||
|
||||
lws_set_log_level(65535, lwsl_emit_syslog);
|
||||
|
||||
context = lws_create_context(info);
|
||||
if (context == NULL) {
|
||||
lwsl_err("Failed to create context\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lws_esp32_romfs = (romfs_t)(void *)_romfs;
|
||||
romfs_size = romfs_mount_check(lws_esp32_romfs);
|
||||
if (!romfs_size) {
|
||||
lwsl_err("Failed to mount ROMFS\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lwsl_notice("ROMFS length %uKiB\n", romfs_size >> 10);
|
||||
|
||||
/* set the lws vfs to use our romfs */
|
||||
|
||||
lws_set_fops(context, &fops);
|
||||
|
||||
if (lws_esp32_is_booting_in_ap_mode() || lws_esp32_force_ap) {
|
||||
info->vhost_name = "ap";
|
||||
info->protocols = protocols_ap;
|
||||
info->mounts = &mount_ap;
|
||||
info->pvo = &ap_pvo;
|
||||
}
|
||||
|
||||
if (!lws_create_vhost(context, info))
|
||||
lwsl_err("Failed to create vhost\n");
|
||||
|
||||
lws_protocol_init(context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
|
@ -669,7 +669,7 @@ _lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
|
|||
fop_fd->pos = r;
|
||||
else
|
||||
lwsl_err("error seeking from cur %ld, offset %ld\n",
|
||||
fop_fd->pos, offset);
|
||||
(long)fop_fd->pos, (long)offset);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -687,7 +687,7 @@ _lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
|
|||
}
|
||||
fop_fd->pos += n;
|
||||
lwsl_debug("%s: read %ld of req %ld, pos %ld, len %ld\n", __func__, n,
|
||||
(long)len, fop_fd->pos, fop_fd->len);
|
||||
(long)len, (long)fop_fd->pos, (long)fop_fd->len);
|
||||
*amount = n;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -108,6 +108,10 @@ LWS_VISIBLE int lws_get_random(struct lws_context *context,
|
|||
|
||||
LWS_VISIBLE int lws_send_pipe_choked(struct lws *wsi)
|
||||
{
|
||||
/* treat the fact we got a truncated send pending as if we're choked */
|
||||
if (wsi->trunc_len)
|
||||
return 1;
|
||||
|
||||
return (int)wsi->sock_send_blocking;
|
||||
}
|
||||
|
||||
|
@ -522,7 +526,7 @@ lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
|
|||
}
|
||||
|
||||
LWS_VISIBLE lws_fop_fd_t
|
||||
_lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
|
||||
_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename,
|
||||
const char *vpath, lws_fop_flags_t *flags)
|
||||
{
|
||||
HANDLE ret;
|
||||
|
|
|
@ -492,7 +492,7 @@ send_raw:
|
|||
wsi->u.http.content_length) {
|
||||
wsi->u.http.content_remain -= len;
|
||||
lwsl_info("%s: content_remain = %lu\n", __func__,
|
||||
wsi->u.http.content_remain);
|
||||
(unsigned long)wsi->u.http.content_remain);
|
||||
if (!wsi->u.http.content_remain) {
|
||||
lwsl_info("%s: selecting final write mode\n", __func__);
|
||||
wp = LWS_WRITE_HTTP_FINAL;
|
||||
|
@ -801,5 +801,5 @@ LWS_VISIBLE int
|
|||
lws_ssl_pending_no_ssl(struct lws *wsi)
|
||||
{
|
||||
(void)wsi;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -955,36 +955,72 @@ LWS_VISIBLE int lws_frame_is_binary(struct lws *wsi)
|
|||
return wsi->u.ws.frame_is_binary;
|
||||
}
|
||||
|
||||
void
|
||||
lws_add_wsi_to_draining_ext_list(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
|
||||
|
||||
if (wsi->u.ws.rx_draining_ext)
|
||||
return;
|
||||
|
||||
lwsl_ext("%s: RX EXT DRAINING: Adding to list\n", __func__);
|
||||
|
||||
wsi->u.ws.rx_draining_ext = 1;
|
||||
wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list;
|
||||
pt->rx_draining_ext_list = wsi;
|
||||
}
|
||||
|
||||
void
|
||||
lws_remove_wsi_from_draining_ext_list(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
|
||||
struct lws **w = &pt->rx_draining_ext_list;
|
||||
|
||||
if (!wsi->u.ws.rx_draining_ext)
|
||||
return;
|
||||
|
||||
lwsl_ext("%s: RX EXT DRAINING: Removing from list\n", __func__);
|
||||
|
||||
wsi->u.ws.rx_draining_ext = 0;
|
||||
|
||||
/* remove us from context draining ext list */
|
||||
while (*w) {
|
||||
if (*w == wsi) {
|
||||
/* if us, point it instead to who we were pointing to */
|
||||
*w = wsi->u.ws.rx_draining_ext_list;
|
||||
break;
|
||||
}
|
||||
w = &((*w)->u.ws.rx_draining_ext_list);
|
||||
}
|
||||
wsi->u.ws.rx_draining_ext_list = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* client-parser.c: lws_client_rx_sm() needs to be roughly kept in
|
||||
* sync with changes here, esp related to ext draining
|
||||
*/
|
||||
|
||||
int
|
||||
lws_rx_sm(struct lws *wsi, unsigned char c)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
|
||||
int callback_action = LWS_CALLBACK_RECEIVE;
|
||||
int ret = 0, n, rx_draining_ext = 0;
|
||||
struct lws_tokens eff_buf;
|
||||
|
||||
eff_buf.token = NULL;
|
||||
eff_buf.token_len = 0;
|
||||
|
||||
if (wsi->socket_is_permanently_unusable)
|
||||
return -1;
|
||||
|
||||
switch (wsi->lws_rx_parse_state) {
|
||||
case LWS_RXPS_NEW:
|
||||
if (wsi->u.ws.rx_draining_ext) {
|
||||
struct lws **w = &pt->rx_draining_ext_list;
|
||||
|
||||
eff_buf.token = NULL;
|
||||
eff_buf.token_len = 0;
|
||||
wsi->u.ws.rx_draining_ext = 0;
|
||||
/* remove us from context draining ext list */
|
||||
while (*w) {
|
||||
if (*w == wsi) {
|
||||
*w = wsi->u.ws.rx_draining_ext_list;
|
||||
break;
|
||||
}
|
||||
w = &((*w)->u.ws.rx_draining_ext_list);
|
||||
}
|
||||
wsi->u.ws.rx_draining_ext_list = NULL;
|
||||
lws_remove_wsi_from_draining_ext_list(wsi);
|
||||
rx_draining_ext = 1;
|
||||
lwsl_err("%s: doing draining flow\n", __func__);
|
||||
lwsl_debug("%s: doing draining flow\n", __func__);
|
||||
|
||||
goto drain_extension;
|
||||
}
|
||||
|
@ -1238,6 +1274,9 @@ handle_first:
|
|||
case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
|
||||
assert(wsi->u.ws.rx_ubuf);
|
||||
|
||||
if (wsi->u.ws.rx_draining_ext)
|
||||
goto drain_extension;
|
||||
|
||||
if (wsi->u.ws.rx_ubuf_head + LWS_PRE >=
|
||||
wsi->u.ws.rx_ubuf_alloc) {
|
||||
lwsl_err("Attempted overflow \n");
|
||||
|
@ -1413,6 +1452,9 @@ drain_extension:
|
|||
goto already_done;
|
||||
|
||||
n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &eff_buf, 0);
|
||||
/* eff_buf may be pointing somewhere completely different now,
|
||||
* it's the output
|
||||
*/
|
||||
if (n < 0) {
|
||||
/*
|
||||
* we may rely on this to get RX, just drop connection
|
||||
|
@ -1426,10 +1468,9 @@ drain_extension:
|
|||
|
||||
if (n && eff_buf.token_len) {
|
||||
/* extension had more... main loop will come back */
|
||||
wsi->u.ws.rx_draining_ext = 1;
|
||||
wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list;
|
||||
pt->rx_draining_ext_list = wsi;
|
||||
}
|
||||
lws_add_wsi_to_draining_ext_list(wsi);
|
||||
} else
|
||||
lws_remove_wsi_from_draining_ext_list(wsi);
|
||||
|
||||
if (eff_buf.token_len > 0 ||
|
||||
callback_action == LWS_CALLBACK_RECEIVE_PONG) {
|
||||
|
|
20
lib/pollfd.c
20
lib/pollfd.c
|
@ -33,6 +33,26 @@ _lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa)
|
|||
if (!wsi || wsi->position_in_fds_table < 0)
|
||||
return 0;
|
||||
|
||||
if (wsi->handling_pollout && !_and && _or == LWS_POLLOUT) {
|
||||
/*
|
||||
* Happening alongside service thread handling POLLOUT.
|
||||
* The danger is when he is finished, he will disable POLLOUT,
|
||||
* countermanding what we changed here.
|
||||
*
|
||||
* Instead of changing the fds, inform the service thread
|
||||
* what happened, and ask it to leave POLLOUT active on exit
|
||||
*/
|
||||
wsi->leave_pollout_active = 1;
|
||||
/*
|
||||
* by definition service thread is not in poll wait, so no need
|
||||
* to cancel service
|
||||
*/
|
||||
|
||||
lwsl_debug("%s: using leave_pollout_active\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
context = wsi->context;
|
||||
pt = &context->pt[(int)wsi->tsi];
|
||||
assert(wsi->position_in_fds_table >= 0 &&
|
||||
|
|
|
@ -367,11 +367,23 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#if defined(__sun) && defined(__GNUC__)
|
||||
|
||||
#include <arpa/nameser_compat.h>
|
||||
|
||||
#if !defined (BYTE_ORDER)
|
||||
# define BYTE_ORDER __BYTE_ORDER__
|
||||
#endif
|
||||
|
||||
#if !defined(LITTLE_ENDIAN)
|
||||
# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
|
||||
#endif
|
||||
|
||||
#if !defined(BIG_ENDIAN)
|
||||
# define BIG_ENDIAN __ORDER_BIG_ENDIAN__
|
||||
#endif
|
||||
|
||||
#endif /* sun + GNUC */
|
||||
|
||||
#if !defined(BYTE_ORDER)
|
||||
# define BYTE_ORDER __BYTE_ORDER
|
||||
#endif
|
||||
|
@ -1445,7 +1457,7 @@ struct lws {
|
|||
unsigned int sending_chunked:1;
|
||||
unsigned int already_did_cce:1;
|
||||
unsigned int told_user_closed:1;
|
||||
unsigned int :1;
|
||||
|
||||
#if defined(LWS_WITH_ESP8266)
|
||||
unsigned int pending_send_completion:3;
|
||||
unsigned int close_is_pending_send_completion:1;
|
||||
|
@ -1475,6 +1487,10 @@ struct lws {
|
|||
unsigned int redirect_to_https:1;
|
||||
#endif
|
||||
|
||||
/* volatile to make sure code is aware other thread can change */
|
||||
volatile unsigned int handling_pollout:1;
|
||||
volatile unsigned int leave_pollout_active:1;
|
||||
|
||||
#ifndef LWS_NO_CLIENT
|
||||
unsigned short c_port;
|
||||
#endif
|
||||
|
@ -1977,6 +1993,10 @@ lws_plat_service_periodic(struct lws_context *context);
|
|||
LWS_EXTERN int
|
||||
lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi,
|
||||
struct lws_pollfd *pfd);
|
||||
LWS_EXTERN void
|
||||
lws_add_wsi_to_draining_ext_list(struct lws *wsi);
|
||||
LWS_EXTERN void
|
||||
lws_remove_wsi_from_draining_ext_list(struct lws *wsi);
|
||||
LWS_EXTERN int
|
||||
lws_plat_context_early_init(void);
|
||||
LWS_EXTERN void
|
||||
|
|
216
lib/romfs.c
Normal file
216
lib/romfs.c
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (C) 2017 National Institute of Advanced Industrial Science
|
||||
* and Technology (AIST)
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of AIST nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "romfs.h"
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
#define RFS_STRING_MAX 64
|
||||
|
||||
static u32_be_t cache[(RFS_STRING_MAX + 32) / 4];
|
||||
static romfs_inode_t ci = (romfs_inode_t)cache;
|
||||
static romfs_t cr = (romfs_t)cache;
|
||||
|
||||
static void
|
||||
set_cache(romfs_inode_t inode, size_t len)
|
||||
{
|
||||
spi_flash_read((uint32_t)inode, cache, len);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ntohl(const u32_be_t be)
|
||||
{
|
||||
return ((be >> 24) & 0xff) |
|
||||
((be >> 16) & 0xff) << 8 |
|
||||
((be >> 8) & 0xff) << 16 |
|
||||
(be & 0xff) << 24;
|
||||
}
|
||||
static romfs_inode_t
|
||||
romfs_lookup(romfs_t romfs, romfs_inode_t start, const char *path);
|
||||
|
||||
static int
|
||||
plus_padding(const uint8_t *s)
|
||||
{
|
||||
int n;
|
||||
|
||||
set_cache((romfs_inode_t)s, RFS_STRING_MAX);
|
||||
n = strlen((const char *)cache);
|
||||
|
||||
if (!(n & 15))
|
||||
n += 0x10;
|
||||
|
||||
return (n + 15) & ~15;
|
||||
}
|
||||
|
||||
static romfs_inode_t
|
||||
skip_and_pad(romfs_inode_t ri)
|
||||
{
|
||||
const uint8_t *p = ((const uint8_t *)ri) + sizeof(*ri);
|
||||
|
||||
return (romfs_inode_t)(p + plus_padding(p));
|
||||
}
|
||||
|
||||
size_t
|
||||
romfs_mount_check(romfs_t romfs)
|
||||
{
|
||||
set_cache((romfs_inode_t)romfs, sizeof(*romfs));
|
||||
|
||||
if (cr->magic1 != 0x6d6f722d ||
|
||||
cr->magic2 != 0x2d736631)
|
||||
return 0;
|
||||
|
||||
return ntohl(cr->size);
|
||||
}
|
||||
|
||||
static romfs_inode_t
|
||||
romfs_symlink(romfs_t romfs, romfs_inode_t level, romfs_inode_t i)
|
||||
{
|
||||
const char *p = (const char *)skip_and_pad(i);
|
||||
|
||||
if (*p == '/') {
|
||||
level = skip_and_pad((romfs_inode_t)romfs);
|
||||
p++;
|
||||
}
|
||||
|
||||
return romfs_lookup(romfs, level, p);
|
||||
}
|
||||
|
||||
static romfs_inode_t
|
||||
dir_link(romfs_t romfs, romfs_inode_t i)
|
||||
{
|
||||
set_cache(i, sizeof(*i));
|
||||
return (romfs_inode_t)((const uint8_t *)romfs +
|
||||
ntohl(ci->dir_start));
|
||||
}
|
||||
|
||||
static romfs_inode_t
|
||||
romfs_lookup(romfs_t romfs, romfs_inode_t start, const char *path)
|
||||
{
|
||||
romfs_inode_t level, i = start;
|
||||
const char *p, *n, *cp;
|
||||
uint32_t next_be;
|
||||
|
||||
if (start == (romfs_inode_t)romfs)
|
||||
i = skip_and_pad((romfs_inode_t)romfs);
|
||||
level = i;
|
||||
while (i != (romfs_inode_t)romfs) {
|
||||
p = path;
|
||||
n = ((const char *)i) + sizeof(*i);
|
||||
|
||||
set_cache(i, sizeof(*i));
|
||||
next_be = ci->next;
|
||||
|
||||
cp = (const char *)cache;
|
||||
set_cache((romfs_inode_t)n, RFS_STRING_MAX);
|
||||
|
||||
while (*p && *p != '/' && *cp && *p == *cp) {
|
||||
p++;
|
||||
n++;
|
||||
cp++;
|
||||
}
|
||||
|
||||
if (!*cp && (!*p || *p == '/') &&
|
||||
(ntohl(next_be) & 7) == RFST_HARDLINK) {
|
||||
set_cache(i, sizeof(*i));
|
||||
return (romfs_inode_t)
|
||||
((const uint8_t *)romfs +
|
||||
(ntohl(ci->dir_start) & ~15));
|
||||
}
|
||||
|
||||
if (!*p && !*cp) {
|
||||
set_cache(i, sizeof(*i));
|
||||
if ((ntohl(ci->next) & 7) == RFST_SYMLINK) {
|
||||
i = romfs_symlink(romfs, level, i);
|
||||
continue;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
if (*p == '/' && !*cp) {
|
||||
set_cache(i, sizeof(*i));
|
||||
switch (ntohl(ci->next) & 7) {
|
||||
case RFST_SYMLINK:
|
||||
i = romfs_symlink(romfs, level, i);
|
||||
if (!i)
|
||||
return NULL;
|
||||
i = dir_link(romfs, i);
|
||||
while (*path != '/' && *path)
|
||||
path++;
|
||||
if (!*path)
|
||||
return NULL;
|
||||
path++;
|
||||
continue;
|
||||
case RFST_DIR:
|
||||
path = p + 1;
|
||||
i = dir_link(romfs, i);
|
||||
break;
|
||||
default:
|
||||
path = p + 1;
|
||||
i = skip_and_pad(i);
|
||||
break;
|
||||
}
|
||||
level = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
set_cache(i, sizeof(*i));
|
||||
if (!(ntohl(ci->next) & ~15))
|
||||
return NULL;
|
||||
|
||||
i = (romfs_inode_t)((const uint8_t *)romfs +
|
||||
(ntohl(ci->next) & ~15));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const void *
|
||||
romfs_get_info(romfs_t romfs, const char *path, size_t *len)
|
||||
{
|
||||
romfs_inode_t i;
|
||||
|
||||
if (*path == '/')
|
||||
path++;
|
||||
|
||||
i = romfs_lookup(romfs, (romfs_inode_t)romfs, path);
|
||||
|
||||
if (!i)
|
||||
return NULL;
|
||||
|
||||
set_cache(i, sizeof(*i));
|
||||
*len = ntohl(ci->size);
|
||||
|
||||
return (void *)skip_and_pad(i);
|
||||
}
|
63
lib/romfs.h
Normal file
63
lib/romfs.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2017 National Institute of Advanced Industrial Science
|
||||
* and Technology (AIST)
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of AIST nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
typedef uint32_t u32_be_t;
|
||||
|
||||
struct romfs_superblock {
|
||||
u32_be_t magic1;
|
||||
u32_be_t magic2;
|
||||
u32_be_t size;
|
||||
u32_be_t checksum;
|
||||
};
|
||||
|
||||
struct romfs_i {
|
||||
u32_be_t next;
|
||||
u32_be_t dir_start;
|
||||
u32_be_t size;
|
||||
u32_be_t checksum;
|
||||
};
|
||||
|
||||
enum {
|
||||
RFST_HARDLINK = 0,
|
||||
RFST_DIR = 1,
|
||||
RFST_SYMLINK = 3,
|
||||
};
|
||||
|
||||
typedef const struct romfs_i *romfs_inode_t;
|
||||
typedef const struct romfs_superblock *romfs_t;
|
||||
|
||||
const void *
|
||||
romfs_get_info(romfs_t romfs, const char *path, size_t *len);
|
||||
size_t
|
||||
romfs_mount_check(romfs_t romfs);
|
||||
|
48
lib/server.c
48
lib/server.c
|
@ -391,11 +391,17 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin,
|
|||
/* if it can't be statted, don't try */
|
||||
if (fflags & LWS_FOP_FLAG_VIRTUAL)
|
||||
break;
|
||||
|
||||
#if !defined(WIN32)
|
||||
if (fstat(wsi->u.http.fop_fd->fd, &st)) {
|
||||
lwsl_info("unable to stat %s\n", path);
|
||||
goto bail;
|
||||
}
|
||||
#else
|
||||
if (stat(path, &st)) {
|
||||
lwsl_info("unable to stat %s\n", path);
|
||||
goto bail;
|
||||
}
|
||||
#endif
|
||||
|
||||
wsi->u.http.fop_fd->mod_time = (uint32_t)st.st_mtime;
|
||||
fflags |= LWS_FOP_FLAG_MOD_TIME_VALID;
|
||||
|
@ -1738,8 +1744,17 @@ lws_http_transaction_completed(struct lws *wsi)
|
|||
if (!wsi->more_rx_waiting) {
|
||||
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
|
||||
lws_header_table_detach(wsi, 1);
|
||||
} else
|
||||
} else {
|
||||
lws_header_table_reset(wsi, 1);
|
||||
/*
|
||||
* If we kept the ah, we should restrict the amount
|
||||
* of time we are willing to keep it. Otherwise it
|
||||
* will be bound the whole time the connection remains
|
||||
* open.
|
||||
*/
|
||||
lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE,
|
||||
wsi->vhost->keepalive_timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're (re)starting on headers, need other implied init */
|
||||
|
@ -1998,7 +2013,7 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
|
|||
lws_sockfd_type accept_fd = LWS_SOCK_INVALID;
|
||||
struct allocated_headers *ah;
|
||||
#if LWS_POSIX
|
||||
struct sockaddr_in cli_addr;
|
||||
struct sockaddr_storage cli_addr;
|
||||
socklen_t clilen;
|
||||
#endif
|
||||
int n, len;
|
||||
|
@ -2061,7 +2076,7 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
|
|||
//lwsl_err("wsi %p: missing ah\n", wsi);
|
||||
/* no autoservice beacuse we will do it next */
|
||||
if (lws_header_table_attach(wsi, 0)) {
|
||||
lwsl_err("wsi %p: failed to acquire ah\n", wsi);
|
||||
lwsl_info("wsi %p: failed to acquire ah\n", wsi);
|
||||
goto try_pollout;
|
||||
}
|
||||
}
|
||||
|
@ -2236,7 +2251,7 @@ try_pollout:
|
|||
if (accept_fd < 0) {
|
||||
if (LWS_ERRNO == LWS_EAGAIN ||
|
||||
LWS_ERRNO == LWS_EWOULDBLOCK) {
|
||||
lwsl_err("accept asks to try again\n");
|
||||
// lwsl_err("accept asks to try again\n");
|
||||
break;
|
||||
}
|
||||
lwsl_err("ERROR on accept: %s\n", strerror(LWS_ERRNO));
|
||||
|
@ -2245,8 +2260,17 @@ try_pollout:
|
|||
|
||||
lws_plat_set_socket_options(wsi->vhost, accept_fd);
|
||||
|
||||
lwsl_debug("accepted new conn port %u on fd=%d\n",
|
||||
ntohs(cli_addr.sin_port), accept_fd);
|
||||
#if defined(LWS_USE_IPV6)
|
||||
lwsl_debug("accepted new conn port %u on fd=%d\n",
|
||||
((cli_addr.ss_family == AF_INET6) ?
|
||||
ntohs(((struct sockaddr_in6 *) &cli_addr)->sin6_port) :
|
||||
ntohs(((struct sockaddr_in *) &cli_addr)->sin_port)),
|
||||
accept_fd);
|
||||
#else
|
||||
lwsl_debug("accepted new conn port %u on fd=%d\n",
|
||||
ntohs(((struct sockaddr_in *) &cli_addr)->sin_port),
|
||||
accept_fd);
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* not very beautiful... */
|
||||
|
@ -2370,13 +2394,17 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
|
|||
lwsl_info("file is being provided in gzip\n");
|
||||
}
|
||||
|
||||
if (
|
||||
#if defined(LWS_WITH_RANGES)
|
||||
if (ranges < 2 && content_type && content_type[0])
|
||||
ranges < 2 &&
|
||||
#endif
|
||||
content_type && content_type[0])
|
||||
if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
|
||||
(unsigned char *)content_type,
|
||||
strlen(content_type), &p, end))
|
||||
return -1;
|
||||
|
||||
#if defined(LWS_WITH_RANGES)
|
||||
if (ranges >= 2) { /* multipart byteranges */
|
||||
strncpy(wsi->u.http.multipart_content_type, content_type,
|
||||
sizeof(wsi->u.http.multipart_content_type) - 1);
|
||||
|
@ -2515,6 +2543,7 @@ lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len)
|
|||
}
|
||||
|
||||
if (wsi->u.ws.rx_draining_ext) {
|
||||
// lwsl_notice("draining with 0\n");
|
||||
m = lws_rx_sm(wsi, 0);
|
||||
if (m < 0)
|
||||
return -1;
|
||||
|
@ -2526,7 +2555,8 @@ lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len)
|
|||
wsi->rxflow_pos++;
|
||||
|
||||
/* consume payload bytes efficiently */
|
||||
if (wsi->lws_rx_parse_state ==
|
||||
if (
|
||||
wsi->lws_rx_parse_state ==
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED) {
|
||||
m = lws_payload_until_length_exhausted(wsi, buf, &len);
|
||||
if (wsi->rxflow_buffer)
|
||||
|
|
178
lib/service.c
178
lib/service.c
|
@ -64,6 +64,14 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
|
||||
//lwsl_err("%s: %p\n", __func__, wsi);
|
||||
|
||||
wsi->leave_pollout_active = 0;
|
||||
wsi->handling_pollout = 1;
|
||||
/*
|
||||
* if another thread wants POLLOUT on us, from here on while
|
||||
* handling_pollout is set, he will only set leave_pollout_active.
|
||||
* If we are going to disable POLLOUT, we will check that first.
|
||||
*/
|
||||
|
||||
/*
|
||||
* user callback is lowest priority to get these notifications
|
||||
* actually, since other pending things cannot be disordered
|
||||
|
@ -77,13 +85,13 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
if (lws_issue_raw(wsi, wsi->trunc_alloc + wsi->trunc_offset,
|
||||
wsi->trunc_len) < 0) {
|
||||
lwsl_info("%s signalling to close\n", __func__);
|
||||
return -1;
|
||||
goto bail_die;
|
||||
}
|
||||
/* leave POLLOUT active either way */
|
||||
return 0;
|
||||
goto bail_ok;
|
||||
} else
|
||||
if (wsi->state == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE)
|
||||
return -1; /* retry closing now */
|
||||
goto bail_die; /* retry closing now */
|
||||
|
||||
if (wsi->mode == LWSCM_WSCL_ISSUE_HTTP_BODY)
|
||||
goto user_service;
|
||||
|
@ -105,7 +113,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
wsi->pps = LWS_PPS_NONE;
|
||||
lws_rx_flow_control(wsi, 1);
|
||||
|
||||
return 0; /* leave POLLOUT active */
|
||||
goto bail_ok; /* leave POLLOUT active */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -127,16 +135,16 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
n = lws_write(wsi, &wsi->u.ws.ping_payload_buf[LWS_PRE],
|
||||
wsi->u.ws.ping_payload_len, write_type);
|
||||
if (n < 0)
|
||||
return -1;
|
||||
goto bail_die;
|
||||
|
||||
/* well he is sent, mark him done */
|
||||
wsi->u.ws.ping_pending_flag = 0;
|
||||
if (wsi->u.ws.payload_is_close)
|
||||
/* oh... a close frame was it... then we are done */
|
||||
return -1;
|
||||
goto bail_die;
|
||||
|
||||
/* otherwise for PING, leave POLLOUT active either way */
|
||||
return 0;
|
||||
goto bail_ok;
|
||||
}
|
||||
|
||||
if (wsi->state == LWSS_ESTABLISHED &&
|
||||
|
@ -148,7 +156,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
n = lws_write(wsi, &wsi->u.ws.ping_payload_buf[LWS_PRE],
|
||||
0, LWS_WRITE_PING);
|
||||
if (n < 0)
|
||||
return -1;
|
||||
goto bail_die;
|
||||
|
||||
/*
|
||||
* we apparently were able to send the PING in a reasonable time
|
||||
|
@ -159,7 +167,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
lws_set_timeout(wsi, PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG,
|
||||
wsi->context->timeout_secs);
|
||||
|
||||
return 0;
|
||||
goto bail_ok;
|
||||
}
|
||||
|
||||
/* Priority 4: if we are closing, not allowed to send more data frags
|
||||
|
@ -178,16 +186,16 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
if (wsi->state == LWSS_ESTABLISHED && wsi->u.ws.tx_draining_ext) {
|
||||
lwsl_ext("SERVICING TX EXT DRAINING\n");
|
||||
if (lws_write(wsi, NULL, 0, LWS_WRITE_CONTINUATION) < 0)
|
||||
return -1;
|
||||
goto bail_die;
|
||||
/* leave POLLOUT active */
|
||||
return 0;
|
||||
goto bail_ok;
|
||||
}
|
||||
|
||||
/* Priority 6: user can get the callback
|
||||
*/
|
||||
m = lws_ext_cb_active(wsi, LWS_EXT_CB_IS_WRITEABLE, NULL, 0);
|
||||
if (m)
|
||||
return -1;
|
||||
goto bail_die;
|
||||
#ifndef LWS_NO_EXTENSIONS
|
||||
if (!wsi->extension_data_pending)
|
||||
goto user_service;
|
||||
|
@ -218,7 +226,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
&eff_buf, 0);
|
||||
if (m < 0) {
|
||||
lwsl_err("ext reports fatal error\n");
|
||||
return -1;
|
||||
goto bail_die;
|
||||
}
|
||||
if (m)
|
||||
/*
|
||||
|
@ -234,7 +242,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
eff_buf.token_len);
|
||||
if (n < 0) {
|
||||
lwsl_info("closing from POLLOUT spill\n");
|
||||
return -1;
|
||||
goto bail_die;
|
||||
}
|
||||
/*
|
||||
* Keep amount spilled small to minimize chance of this
|
||||
|
@ -242,7 +250,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
if (n != eff_buf.token_len) {
|
||||
lwsl_err("Unable to spill ext %d vs %d\n",
|
||||
eff_buf.token_len, n);
|
||||
return -1;
|
||||
goto bail_die;
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
|
@ -270,7 +278,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
* when we come back here and there's nothing more to spill.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
goto bail_ok;
|
||||
}
|
||||
#ifndef LWS_NO_EXTENSIONS
|
||||
wsi->extension_data_pending = 0;
|
||||
|
@ -278,15 +286,31 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
user_service:
|
||||
/* one shot */
|
||||
|
||||
if (pollfd)
|
||||
if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {
|
||||
lwsl_info("failed at set pollfd\n");
|
||||
return 1;
|
||||
}
|
||||
if (pollfd) {
|
||||
int eff = wsi->leave_pollout_active;
|
||||
|
||||
if (!eff)
|
||||
if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {
|
||||
lwsl_info("failed at set pollfd\n");
|
||||
goto bail_die;
|
||||
}
|
||||
|
||||
wsi->handling_pollout = 0;
|
||||
|
||||
/* cannot get leave_pollout_active set after the above */
|
||||
|
||||
if (!eff && wsi->leave_pollout_active)
|
||||
/* got set inbetween sampling eff and clearing
|
||||
* handling_pollout, force POLLOUT on */
|
||||
lws_calllback_as_writeable(wsi);
|
||||
|
||||
wsi->leave_pollout_active = 0;
|
||||
}
|
||||
|
||||
if (wsi->mode != LWSCM_WSCL_ISSUE_HTTP_BODY &&
|
||||
!wsi->hdr_parsing_completed)
|
||||
return 0;
|
||||
goto bail_ok;
|
||||
|
||||
|
||||
#ifdef LWS_WITH_CGI
|
||||
user_service_go_again:
|
||||
|
@ -314,7 +338,7 @@ user_service_go_again:
|
|||
wsi->u.http2.requested_POLLOUT = 0;
|
||||
if (!wsi->u.http2.initialized) {
|
||||
lwsl_info("pollout on uninitialized http2 conn\n");
|
||||
return 0;
|
||||
goto bail_ok;
|
||||
}
|
||||
|
||||
lwsl_info("%s: doing children\n", __func__);
|
||||
|
@ -337,10 +361,30 @@ user_service_go_again:
|
|||
|
||||
lwsl_info("%s: completed\n", __func__);
|
||||
|
||||
return 0;
|
||||
goto bail_ok;
|
||||
notify:
|
||||
#endif
|
||||
wsi->handling_pollout = 0;
|
||||
wsi->leave_pollout_active = 0;
|
||||
|
||||
return lws_calllback_as_writeable(wsi);
|
||||
|
||||
/*
|
||||
* since these don't disable the POLLOUT, they are always doing the
|
||||
* right thing for leave_pollout_active whether it was set or not.
|
||||
*/
|
||||
|
||||
bail_ok:
|
||||
wsi->handling_pollout = 0;
|
||||
wsi->leave_pollout_active = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
bail_die:
|
||||
wsi->handling_pollout = 0;
|
||||
wsi->leave_pollout_active = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -489,9 +533,10 @@ lws_service_flag_pending(struct lws_context *context, int tsi)
|
|||
while (wsi) {
|
||||
pt->fds[wsi->position_in_fds_table].revents |=
|
||||
pt->fds[wsi->position_in_fds_table].events & LWS_POLLIN;
|
||||
if (pt->fds[wsi->position_in_fds_table].revents &
|
||||
LWS_POLLIN)
|
||||
if (pt->fds[wsi->position_in_fds_table].revents & LWS_POLLIN) {
|
||||
forced = 1;
|
||||
break;
|
||||
}
|
||||
wsi = wsi->u.ws.rx_draining_ext_list;
|
||||
}
|
||||
|
||||
|
@ -688,6 +733,17 @@ completed:
|
|||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
lws_is_ws_with_ext(struct lws *wsi)
|
||||
{
|
||||
#if defined(LWS_NO_EXTENSIONS)
|
||||
return 0;
|
||||
#else
|
||||
return wsi->state == LWSS_ESTABLISHED &&
|
||||
!!wsi->count_act_ext;
|
||||
#endif
|
||||
}
|
||||
|
||||
LWS_VISIBLE int
|
||||
lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int tsi)
|
||||
{
|
||||
|
@ -839,10 +895,48 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
|
|||
|
||||
#endif
|
||||
|
||||
lwsl_debug("fd=%d, revents=%d\n", pollfd->fd, pollfd->revents);
|
||||
// lwsl_debug("fd=%d, revents=%d, mode=%d, state=%d\n", pollfd->fd, pollfd->revents, (int)wsi->mode, (int)wsi->state);
|
||||
if (pollfd->revents & LWS_POLLHUP)
|
||||
goto close_and_handled;
|
||||
|
||||
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
if ((wsi->state == LWSS_SHUTDOWN) && lws_is_ssl(wsi) && wsi->ssl)
|
||||
{
|
||||
n = SSL_shutdown(wsi->ssl);
|
||||
lwsl_debug("SSL_shutdown=%d for fd %d\n", n, wsi->desc.sockfd);
|
||||
if (n == 1)
|
||||
{
|
||||
n = shutdown(wsi->desc.sockfd, SHUT_WR);
|
||||
goto close_and_handled;
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
|
||||
n = 0;
|
||||
goto handled;
|
||||
}
|
||||
else /* n < 0 */
|
||||
{
|
||||
int shutdown_error = SSL_get_error(wsi->ssl, n);
|
||||
lwsl_debug("SSL_shutdown returned %d, SSL_get_error: %d\n", n, shutdown_error);
|
||||
if (shutdown_error == SSL_ERROR_WANT_READ) {
|
||||
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
|
||||
n = 0;
|
||||
goto handled;
|
||||
} else if (shutdown_error == SSL_ERROR_WANT_WRITE) {
|
||||
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLOUT);
|
||||
n = 0;
|
||||
goto handled;
|
||||
}
|
||||
|
||||
// actual error occurred, just close the connection
|
||||
n = shutdown(wsi->desc.sockfd, SHUT_WR);
|
||||
goto close_and_handled;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* okay, what we came here to do... */
|
||||
|
||||
switch (wsi->mode) {
|
||||
|
@ -1010,9 +1104,24 @@ read:
|
|||
wsi->u.hdr.ah->rxpos;
|
||||
} else {
|
||||
if (wsi->mode != LWSCM_HTTP_CLIENT_ACCEPTED) {
|
||||
/*
|
||||
* extension may not consume everything (eg, pmd may be constrained
|
||||
* as to what it can output...) has to go in per-wsi rx buf area.
|
||||
* Otherwise in large temp serv_buf area.
|
||||
*/
|
||||
eff_buf.token = (char *)pt->serv_buf;
|
||||
if (lws_is_ws_with_ext(wsi)) {
|
||||
eff_buf.token_len = wsi->u.ws.rx_ubuf_alloc;
|
||||
} else {
|
||||
eff_buf.token_len = context->pt_serv_buf_size;
|
||||
}
|
||||
|
||||
if (eff_buf.token_len > context->pt_serv_buf_size)
|
||||
eff_buf.token_len = context->pt_serv_buf_size;
|
||||
|
||||
eff_buf.token_len = lws_ssl_capable_read(wsi,
|
||||
pt->serv_buf, pending ? pending :
|
||||
context->pt_serv_buf_size);
|
||||
(unsigned char *)eff_buf.token, pending ? pending :
|
||||
eff_buf.token_len);
|
||||
switch (eff_buf.token_len) {
|
||||
case 0:
|
||||
lwsl_info("%s: zero length read\n", __func__);
|
||||
|
@ -1025,8 +1134,7 @@ read:
|
|||
lwsl_info("Closing when error\n");
|
||||
goto close_and_handled;
|
||||
}
|
||||
|
||||
eff_buf.token = (char *)pt->serv_buf;
|
||||
// lwsl_notice("Actual RX %d\n", eff_buf.token_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1092,6 +1200,8 @@ drain:
|
|||
* around again it will pick up from where it
|
||||
* left off.
|
||||
*/
|
||||
// lwsl_notice("doing lws_read from pt->serv_buf %p %p for len %d\n", pt->serv_buf, eff_buf.token, (int)eff_buf.token_len);
|
||||
|
||||
n = lws_read(wsi, (unsigned char *)eff_buf.token,
|
||||
eff_buf.token_len);
|
||||
if (n < 0) {
|
||||
|
@ -1118,7 +1228,11 @@ drain:
|
|||
|
||||
pending = lws_ssl_pending(wsi);
|
||||
if (pending) {
|
||||
pending = pending > context->pt_serv_buf_size ?
|
||||
if (lws_is_ws_with_ext(wsi))
|
||||
pending = pending > wsi->u.ws.rx_ubuf_alloc ?
|
||||
wsi->u.ws.rx_ubuf_alloc : pending;
|
||||
else
|
||||
pending = pending > context->pt_serv_buf_size ?
|
||||
context->pt_serv_buf_size : pending;
|
||||
goto read;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2016 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
|
|
|
@ -382,7 +382,7 @@ lws_ssl_client_connect2(struct lws *wsi)
|
|||
int lws_context_init_client_ssl(struct lws_context_creation_info *info,
|
||||
struct lws_vhost *vhost)
|
||||
{
|
||||
SSL_METHOD *method;
|
||||
SSL_METHOD *method = NULL;
|
||||
struct lws wsi;
|
||||
unsigned long error;
|
||||
const char *cipher_list = info->ssl_cipher_list;
|
||||
|
@ -421,7 +421,14 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
|
|||
|
||||
/* basic openssl init already happened in context init */
|
||||
|
||||
/* choose the most recent spin of the api */
|
||||
#if defined(LWS_HAVE_TLS_CLIENT_METHOD)
|
||||
method = (SSL_METHOD *)TLS_client_method();
|
||||
#elif defined(LWS_HAVE_TLSV1_2_CLIENT_METHOD)
|
||||
method = (SSL_METHOD *)TLSv1_2_client_method();
|
||||
#else
|
||||
method = (SSL_METHOD *)SSLv23_client_method();
|
||||
#endif
|
||||
if (!method) {
|
||||
error = ERR_get_error();
|
||||
lwsl_err("problem creating ssl method %lu: %s\n",
|
||||
|
|
10
lib/ssl.c
10
lib/ssl.c
|
@ -21,6 +21,10 @@
|
|||
|
||||
#include "private-libwebsockets.h"
|
||||
|
||||
/* workaround for mingw */
|
||||
#if !defined(ECONNABORTED)
|
||||
#define ECONNABORTED 103
|
||||
#endif
|
||||
|
||||
int openssl_websocket_private_data_index,
|
||||
openssl_SSL_CTX_private_data_index;
|
||||
|
@ -57,13 +61,13 @@ char* lws_ssl_get_error_string(int status, int ret, char *buf, size_t len) {
|
|||
case SSL_ERROR_SYSCALL:
|
||||
switch (ret) {
|
||||
case 0:
|
||||
snprintf(buf, len, "SSL_ERROR_SYSCALL: EOF");
|
||||
lws_snprintf(buf, len, "SSL_ERROR_SYSCALL: EOF");
|
||||
return buf;
|
||||
case -1:
|
||||
#ifndef LWS_PLAT_OPTEE
|
||||
snprintf(buf, len, "SSL_ERROR_SYSCALL: %s", strerror(errno));
|
||||
lws_snprintf(buf, len, "SSL_ERROR_SYSCALL: %s", strerror(errno));
|
||||
#else
|
||||
snprintf(buf, len, "SSL_ERROR_SYSCALL: %d", errno);
|
||||
lws_snprintf(buf, len, "SSL_ERROR_SYSCALL: %d", errno);
|
||||
#endif
|
||||
return buf;
|
||||
default:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Name: libwebsockets
|
||||
Version: 2.2.0
|
||||
Version: 2.2.2
|
||||
Release: 1%{?dist}
|
||||
Summary: Websocket Server and Client Library
|
||||
|
||||
|
@ -60,6 +60,8 @@ rm -rf $RPM_BUILD_ROOT
|
|||
/%{_libdir}/cmake/libwebsockets/LibwebsocketsConfig.cmake
|
||||
/%{_libdir}/cmake/libwebsockets/LibwebsocketsConfigVersion.cmake
|
||||
/%{_libdir}/cmake/libwebsockets/LibwebsocketsTargets.cmake
|
||||
/%{_libdir}/cmake/libwebsockets/LibwebsocketsTargets-release.cmake
|
||||
|
||||
/usr/share/libwebsockets-test-server
|
||||
%doc
|
||||
%files devel
|
||||
|
@ -70,6 +72,9 @@ rm -rf $RPM_BUILD_ROOT
|
|||
/%{_libdir}/pkgconfig/libwebsockets.pc
|
||||
|
||||
%changelog
|
||||
* Mon Mar 06 2017 Andy Green <andy@warmcat.com> 2.2.2-1
|
||||
- MINOR Upstream 2.2.2 release
|
||||
|
||||
* Mon Mar 06 2017 Andy Green <andy@warmcat.com> 2.2.0-1
|
||||
- MAJOR SONAMEBUMP APICHANGES Upstream 2.2.0 release
|
||||
|
||||
|
|
|
@ -127,4 +127,10 @@
|
|||
#cmakedefine LWS_HAVE_STDINT_H
|
||||
|
||||
#cmakedefine LWS_FALLBACK_GETHOSTBYNAME
|
||||
|
||||
/* OpenSSL various APIs */
|
||||
|
||||
#cmakedefine LWS_HAVE_TLS_CLIENT_METHOD
|
||||
#cmakedefine LWS_HAVE_TLSV1_2_CLIENT_METHOD
|
||||
|
||||
${LWS_SIZEOFPTR_CODE}
|
||||
|
|
|
@ -219,11 +219,11 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
case 'h':
|
||||
fprintf(stderr, "Usage: lwsws [-c <config dir>] "
|
||||
"[-d <log bitfield>] [-D] [--help]\n");
|
||||
"[-d <log bitfield>] [--help]\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
/*
|
||||
* We leave our original process up permanently, because that
|
||||
* suits systemd.
|
||||
|
@ -267,7 +267,7 @@ int main(int argc, char **argv)
|
|||
// !!! implemenation needed
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
/* child process */
|
||||
|
||||
#ifndef _WIN32
|
||||
|
|
|
@ -17,6 +17,9 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGE} ${PACKAGE_VERSION}")
|
|||
set(SOVERSION "1")
|
||||
set(VERSION "0.1")
|
||||
|
||||
set(PLUGIN_NAME "protocol_example_standalone")
|
||||
# space-separated list of sources
|
||||
set(PLUGIN_SRCS protocol_example_standalone.c)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
|
||||
|
||||
|
@ -50,29 +53,21 @@ endif()
|
|||
|
||||
set(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
|
||||
|
||||
macro(create_plugin PLUGIN_NAME MAIN_SRC)
|
||||
set(PLUGIN_SRCS ${MAIN_SRC})
|
||||
|
||||
source_group("Headers Private" FILES ${PLUGIN_HDR})
|
||||
source_group("Sources" FILES ${PLUGIN_SRCS})
|
||||
add_library(${PLUGIN_NAME} SHARED ${PLUGIN_SRCS} ${PLUGIN_HDR})
|
||||
|
||||
target_link_libraries(${PLUGIN_NAME} -lwebsockets)
|
||||
|
||||
# Set test app specific defines.
|
||||
set_property(TARGET ${PLUGIN_NAME}
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
INSTALL_DATADIR="${CMAKE_INSTALL_PREFIX}/plugins"
|
||||
)
|
||||
|
||||
list(APPEND PLUGINS_LIST ${PLUGIN_NAME})
|
||||
endmacro()
|
||||
source_group("Headers Private" FILES ${PLUGIN_HDR})
|
||||
source_group("Sources" FILES ${PLUGIN_SRCS})
|
||||
add_library(${PLUGIN_NAME} SHARED ${PLUGIN_SRCS} ${PLUGIN_HDR})
|
||||
|
||||
target_link_libraries(${PLUGIN_NAME} -lwebsockets)
|
||||
|
||||
create_plugin(protocol_example_standalone
|
||||
"protocol_example_standalone.c")
|
||||
# Set test app specific defines.
|
||||
set_property(TARGET ${PLUGIN_NAME}
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
INSTALL_DATADIR="${CMAKE_INSTALL_PREFIX}/plugins"
|
||||
)
|
||||
|
||||
list(APPEND PLUGINS_LIST ${PLUGIN_NAME})
|
||||
|
||||
install(TARGETS ${PLUGINS_LIST}
|
||||
PERMISSIONS OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE OWNER_READ GROUP_READ WORLD_READ
|
||||
DESTINATION share/libwebsockets-test-server/plugins
|
||||
COMPONENT plugins)
|
||||
COMPONENT plugins)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
|
|
333
plugins/protocol_esp32_lws_scan.c
Normal file
333
plugins/protocol_esp32_lws_scan.c
Normal file
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
* Example ESP32 app code using Libwebsockets
|
||||
*
|
||||
* Copyright (C) 2017 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* The person who associated a work with this deed has dedicated
|
||||
* the work to the public domain by waiving all of his or her rights
|
||||
* to the work worldwide under copyright law, including all related
|
||||
* and neighboring rights, to the extent allowed by law. You can copy,
|
||||
* modify, distribute and perform the work, even for commercial purposes,
|
||||
* all without asking permission.
|
||||
*
|
||||
* The test apps are intended to be adapted for use in your code, which
|
||||
* may be proprietary. So unlike the library itself, they are licensed
|
||||
* Public Domain.
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <nvs.h>
|
||||
|
||||
typedef enum {
|
||||
SCAN_STATE_NONE,
|
||||
SCAN_STATE_INITIAL,
|
||||
SCAN_STATE_LIST,
|
||||
SCAN_STATE_FINAL
|
||||
} scan_state;
|
||||
|
||||
struct store_json {
|
||||
const char *j;
|
||||
const char *nvs;
|
||||
};
|
||||
|
||||
struct per_session_data__esplws_scan {
|
||||
struct per_session_data__esplws_scan *next;
|
||||
scan_state scan_state;
|
||||
char ap_record;
|
||||
unsigned char subsequent:1;
|
||||
unsigned char changed_partway:1;
|
||||
};
|
||||
|
||||
struct per_vhost_data__esplws_scan {
|
||||
wifi_ap_record_t ap_records[20];
|
||||
TimerHandle_t timer;
|
||||
struct per_session_data__esplws_scan *live_pss_list;
|
||||
struct lws_context *context;
|
||||
struct lws_vhost *vhost;
|
||||
const struct lws_protocols *protocol;
|
||||
uint16_t count_ap_records;
|
||||
char count_live_pss;
|
||||
unsigned char scan_ongoing:1;
|
||||
unsigned char completed_any_scan:1;
|
||||
unsigned char reboot:1;
|
||||
};
|
||||
|
||||
static const struct store_json store_json[] = {
|
||||
{ "ssid\":\"", "ssid" },
|
||||
{ ",\"pw\":\"", "password" },
|
||||
{ ",\"serial\":\"", "serial" },
|
||||
{ ",\"region\":\"", "region" },
|
||||
};
|
||||
|
||||
static wifi_scan_config_t scan_config = {
|
||||
.ssid = 0,
|
||||
.bssid = 0,
|
||||
.channel = 0,
|
||||
.show_hidden = true
|
||||
};
|
||||
|
||||
extern void (*lws_cb_scan_done)(void *);
|
||||
extern void *lws_cb_scan_done_arg;
|
||||
|
||||
|
||||
static void
|
||||
scan_finished(void *v);
|
||||
|
||||
static int
|
||||
esplws_simple_arg(char *dest, int len, const char *in, const char *match)
|
||||
{
|
||||
const char *p = strstr(in, match);
|
||||
int n = 0;
|
||||
|
||||
if (!p) {
|
||||
lwsl_err("No match %s\n", match);
|
||||
return 1;
|
||||
}
|
||||
|
||||
p += strlen(match);
|
||||
while (*p && *p != '\"' && n < len - 1)
|
||||
dest[n++] = *p++;
|
||||
dest[n] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
scan_start(struct per_vhost_data__esplws_scan *vhd)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (vhd->reboot)
|
||||
esp_restart();
|
||||
|
||||
if (vhd->scan_ongoing)
|
||||
return;
|
||||
|
||||
vhd->scan_ongoing = 1;
|
||||
lws_cb_scan_done = scan_finished;
|
||||
lws_cb_scan_done_arg = vhd;
|
||||
n = esp_wifi_scan_start(&scan_config, false);
|
||||
if (n != ESP_OK)
|
||||
lwsl_err("scan start failed %d\n", n);
|
||||
}
|
||||
|
||||
static void timer_cb(TimerHandle_t t)
|
||||
{
|
||||
struct per_vhost_data__esplws_scan *vhd = pvTimerGetTimerID(t);
|
||||
|
||||
scan_start(vhd);
|
||||
}
|
||||
|
||||
static void
|
||||
scan_finished(void *v)
|
||||
{
|
||||
struct per_vhost_data__esplws_scan *vhd = v;
|
||||
struct per_session_data__esplws_scan *p = vhd->live_pss_list;
|
||||
|
||||
vhd->scan_ongoing = 0;
|
||||
|
||||
vhd->count_ap_records = ARRAY_SIZE(vhd->ap_records);
|
||||
if (esp_wifi_scan_get_ap_records(&vhd->count_ap_records, vhd->ap_records) != ESP_OK) {
|
||||
lwsl_err("%s: failed\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
while (p) {
|
||||
if (p->scan_state != SCAN_STATE_INITIAL && p->scan_state != SCAN_STATE_NONE)
|
||||
p->changed_partway = 1;
|
||||
else
|
||||
p->scan_state = SCAN_STATE_INITIAL;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
lws_callback_on_writable_all_protocol(vhd->context, vhd->protocol);
|
||||
}
|
||||
|
||||
static int
|
||||
callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct per_session_data__esplws_scan *pss =
|
||||
(struct per_session_data__esplws_scan *)user;
|
||||
struct per_vhost_data__esplws_scan *vhd =
|
||||
(struct per_vhost_data__esplws_scan *)
|
||||
lws_protocol_vh_priv_get(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi));
|
||||
char buf[LWS_PRE + 384], /*ip[24],*/ *start = buf + LWS_PRE - 1, *p = start,
|
||||
*end = buf + sizeof(buf) - 1;
|
||||
wifi_ap_record_t *r;
|
||||
int n, m;
|
||||
|
||||
switch (reason) {
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_INIT:
|
||||
vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi),
|
||||
sizeof(struct per_vhost_data__esplws_scan));
|
||||
vhd->context = lws_get_context(wsi);
|
||||
vhd->protocol = lws_get_protocol(wsi);
|
||||
vhd->vhost = lws_get_vhost(wsi);
|
||||
vhd->timer = xTimerCreate("x", pdMS_TO_TICKS(10000), 1, vhd,
|
||||
(TimerCallbackFunction_t)timer_cb);
|
||||
xTimerStart(vhd->timer, 0);
|
||||
vhd->scan_ongoing = 0;
|
||||
scan_start(vhd);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_DESTROY:
|
||||
if (!vhd)
|
||||
break;
|
||||
xTimerStop(vhd->timer, 0);
|
||||
xTimerDelete(vhd->timer, 0);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_ESTABLISHED:
|
||||
vhd->count_live_pss++;
|
||||
pss->next = vhd->live_pss_list;
|
||||
vhd->live_pss_list = pss;
|
||||
/* if we have scan results, update them. Otherwise wait */
|
||||
if (vhd->count_ap_records) {
|
||||
pss->scan_state = SCAN_STATE_INITIAL;
|
||||
lws_callback_on_writable(wsi);
|
||||
}
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_SERVER_WRITEABLE:
|
||||
switch (pss->scan_state) {
|
||||
case SCAN_STATE_INITIAL:
|
||||
n = LWS_WRITE_TEXT | LWS_WRITE_NO_FIN;;
|
||||
p += snprintf(p, end - p,
|
||||
"{ \"model\":\"%s\","
|
||||
" \"serial\":\"%s\","
|
||||
" \"host\":\"%s-%s\","
|
||||
" \"region\":\"%d\","
|
||||
" \"aps\":[",
|
||||
lws_esp32_model,
|
||||
lws_esp32_serial,
|
||||
lws_esp32_model, lws_esp32_serial,
|
||||
lws_esp32_region);
|
||||
pss->scan_state = SCAN_STATE_LIST;
|
||||
pss->ap_record = 0;
|
||||
pss->subsequent = 0;
|
||||
break;
|
||||
case SCAN_STATE_LIST:
|
||||
n = LWS_WRITE_CONTINUATION | LWS_WRITE_NO_FIN;
|
||||
if (pss->ap_record >= vhd->count_ap_records)
|
||||
goto scan_state_final;
|
||||
|
||||
if (pss->subsequent)
|
||||
*p++ = ',';
|
||||
pss->subsequent = 1;
|
||||
|
||||
r = &vhd->ap_records[(int)pss->ap_record++];
|
||||
p += snprintf(p, end - p,
|
||||
"{\"ssid\":\"%s\","
|
||||
"\"bssid\":\"%02X:%02X:%02X:%02X:%02X:%02X\","
|
||||
"\"rssi\":\"%d\","
|
||||
"\"chan\":\"%d\","
|
||||
"\"auth\":\"%d\"}",
|
||||
r->ssid,
|
||||
r->bssid[0], r->bssid[1], r->bssid[2],
|
||||
r->bssid[3], r->bssid[4], r->bssid[5],
|
||||
r->rssi, r->primary, r->authmode);
|
||||
if (pss->ap_record >= vhd->count_ap_records)
|
||||
pss->scan_state = SCAN_STATE_FINAL;
|
||||
break;
|
||||
|
||||
case SCAN_STATE_FINAL:
|
||||
scan_state_final:
|
||||
n = LWS_WRITE_CONTINUATION;
|
||||
p += sprintf(p, "]}");
|
||||
if (pss->changed_partway) {
|
||||
pss->subsequent = 0;
|
||||
pss->scan_state = SCAN_STATE_INITIAL;
|
||||
} else
|
||||
pss->scan_state = SCAN_STATE_NONE;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
m = lws_write(wsi, (unsigned char *)start, p - start, n);
|
||||
if (m < 0) {
|
||||
lwsl_err("ERROR %d writing to di socket\n", m);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pss->scan_state != SCAN_STATE_NONE)
|
||||
lws_callback_on_writable(wsi);
|
||||
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
{
|
||||
nvs_handle nvh;
|
||||
char p[64];
|
||||
int n;
|
||||
|
||||
if (strstr((const char *)in, "identify")) {
|
||||
lws_esp32_identify_physical_device();
|
||||
break;
|
||||
}
|
||||
|
||||
if (nvs_open("lws-station", NVS_READWRITE, &nvh) != ESP_OK) {
|
||||
lwsl_err("Unable to open nvs\n");
|
||||
break;
|
||||
}
|
||||
|
||||
for (n = 0; n < ARRAY_SIZE(store_json); n++) {
|
||||
if (esplws_simple_arg(p, sizeof(p), in, store_json[n].j))
|
||||
goto bail_nvs;
|
||||
|
||||
if (nvs_set_str(nvh, store_json[n].nvs, p) != ESP_OK) {
|
||||
lwsl_err("Unable to store %s in nvm\n", store_json[n].nvs);
|
||||
goto bail_nvs;
|
||||
}
|
||||
}
|
||||
|
||||
nvs_commit(nvh);
|
||||
nvs_close(nvh);
|
||||
|
||||
vhd->reboot = 1;
|
||||
break;
|
||||
|
||||
bail_nvs:
|
||||
nvs_close(nvh);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
case LWS_CALLBACK_CLOSED:
|
||||
{
|
||||
struct per_session_data__esplws_scan **p = &vhd->live_pss_list;
|
||||
|
||||
while (*p) {
|
||||
if ((*p) == pss) {
|
||||
*p = pss->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
p = &((*p)->next);
|
||||
}
|
||||
|
||||
vhd->count_live_pss--;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LWS_PLUGIN_PROTOCOL_ESPLWS_SCAN \
|
||||
{ \
|
||||
"esplws-scan", \
|
||||
callback_esplws_scan, \
|
||||
sizeof(struct per_session_data__esplws_scan), \
|
||||
512, 0, NULL \
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ uv_timeout_cb_server_status(uv_timer_t *w
|
|||
l -= n;
|
||||
}
|
||||
fd = open(fp->filepath, LWS_O_RDONLY);
|
||||
if (fd != LWS_INVALID_FILE) {
|
||||
if (fd >= 0) {
|
||||
n = read(fd, contents, sizeof(contents) - 1);
|
||||
if (n >= 0) {
|
||||
contents[n] = '\0';
|
||||
|
|
|
@ -200,6 +200,11 @@ walk_final:
|
|||
lws_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
lwsl_notice("pmd test: RX len %d\n", (int)len);
|
||||
puts(in);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLOSED:
|
||||
pss1 = vhd->live_pss_list;
|
||||
pss2 = NULL;
|
||||
|
|
|
@ -74,7 +74,7 @@ file_upload_cb(void *data, const char *name, const char *filename,
|
|||
* simple demo use a fixed name so we don't have to deal with
|
||||
* attacks */
|
||||
#if !defined(LWS_WITH_ESP8266)
|
||||
pss->fd = open("/tmp/post-file",
|
||||
pss->fd = (lws_filefd_type)open("/tmp/post-file",
|
||||
O_CREAT | O_TRUNC | O_RDWR, 0600);
|
||||
#endif
|
||||
break;
|
||||
|
@ -88,7 +88,7 @@ file_upload_cb(void *data, const char *name, const char *filename,
|
|||
return 1;
|
||||
|
||||
#if !defined(LWS_WITH_ESP8266)
|
||||
n = write(pss->fd, buf, len);
|
||||
n = write((int)pss->fd, buf, len);
|
||||
lwsl_notice("%s: write %d says %d\n", __func__, len, n);
|
||||
#else
|
||||
lwsl_notice("%s: Received chunk size %d\n", __func__, len);
|
||||
|
@ -97,7 +97,7 @@ file_upload_cb(void *data, const char *name, const char *filename,
|
|||
if (state == LWS_UFS_CONTENT)
|
||||
break;
|
||||
#if !defined(LWS_WITH_ESP8266)
|
||||
close(pss->fd);
|
||||
close((int)pss->fd);
|
||||
pss->fd = LWS_INVALID_FILE;
|
||||
#endif
|
||||
break;
|
||||
|
|
|
@ -147,7 +147,7 @@ file_upload_cb(void *data, const char *name, const char *filename,
|
|||
/* we get the original filename in @filename arg, but for
|
||||
* simple demo use a fixed name so we don't have to deal with
|
||||
* attacks */
|
||||
pss->post_fd = open("/tmp/post-file",
|
||||
pss->post_fd = (lws_filefd_type)open("/tmp/post-file",
|
||||
O_CREAT | O_TRUNC | O_RDWR, 0600);
|
||||
break;
|
||||
case LWS_UFS_FINAL_CONTENT:
|
||||
|
@ -159,12 +159,12 @@ file_upload_cb(void *data, const char *name, const char *filename,
|
|||
if (pss->file_length > 100000)
|
||||
return 1;
|
||||
|
||||
n = write(pss->post_fd, buf, len);
|
||||
n = write((int)pss->post_fd, buf, len);
|
||||
lwsl_notice("%s: write %d says %d\n", __func__, len, n);
|
||||
}
|
||||
if (state == LWS_UFS_CONTENT)
|
||||
break;
|
||||
close(pss->post_fd);
|
||||
close((int)pss->post_fd);
|
||||
pss->post_fd = LWS_INVALID_FILE;
|
||||
break;
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
|
|||
struct per_session_data__http *pss =
|
||||
(struct per_session_data__http *)user;
|
||||
unsigned char buffer[4096 + LWS_PRE];
|
||||
unsigned long amount, file_len, sent;
|
||||
lws_filepos_t amount, file_len, sent;
|
||||
char leaf_path[1024];
|
||||
const char *mimetype;
|
||||
char *other_headers;
|
||||
|
|
|
@ -131,6 +131,11 @@ callback_lws_status(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
update_status(wsi, pss);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
lwsl_notice("pmd test: RX len %d\n", (int)len);
|
||||
puts(in);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_SERVER_WRITEABLE:
|
||||
m = lws_write(wsi, (unsigned char *)cache + LWS_PRE, cache_len,
|
||||
LWS_WRITE_TEXT);
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue