فهرست منبع

2020.04.25 / Folus Wen

Actions:
1. Websocket library upgrade from V2.1 to V2.2.2 fix Enelx wss can not connect issus.
2. EVSE/Modularization/Makefile OcppBackend compile parameter modify for libwebsocket upgrade
3. EVSE/rootfs/lib/libwebsockets.so.9 remove.
4. linux-devkit/sysroots/armv7ahf-neon-linux-gnueabi/usr/lib/libcrypto.so.1.0.0 change to version 1.0.2g
5. linux-devkit/sysroots/armv7ahf-neon-linux-gnueabi/usr/lib/libssl.so.1.0.0 change to version 1.0.2g

Files:
1. As follow commit history

Image version: D0.00.XX.XXXX.XX
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 4 سال پیش
والد
کامیت
8a0cca1bfe
100فایلهای تغییر یافته به همراه7711 افزوده شده و 1767 حذف شده
  1. 6 6
      EVSE/GPL/Makefile
  2. BIN
      EVSE/GPL/libwebsockets-2.2.2-stable-org.tar.gz
  3. 2 1
      EVSE/GPL/libwebsockets-2.2.2-stable-org/.gitignore
  4. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/.travis.yml
  5. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/Android.mk
  6. 213 129
      EVSE/GPL/libwebsockets-2.2.2-stable-org/CMakeLists.txt
  7. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/FindLibWebSockets.cmake
  8. 9 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/Kconfig
  9. 12 4
      EVSE/GPL/libwebsockets-2.2.2-stable-org/LICENSE
  10. 46 42
      EVSE/GPL/libwebsockets-2.2.2-stable-org/README.build.md
  11. 200 10
      EVSE/GPL/libwebsockets-2.2.2-stable-org/README.coding.md
  12. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/README.esp8266.md
  13. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/README.generic-sessions.md
  14. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/README.generic-table.md
  15. 111 12
      EVSE/GPL/libwebsockets-2.2.2-stable-org/README.lwsws.md
  16. 2 2
      EVSE/GPL/libwebsockets-2.2.2-stable-org/README.md
  17. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/README.problems.md
  18. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/README.test-apps.md
  19. 5 3
      EVSE/GPL/libwebsockets-2.2.2-stable-org/appveyor.yml
  20. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/autobahn-test.sh
  21. 69 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/changelog
  22. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/FindGit.cmake
  23. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/FindOpenSSLbins.cmake
  24. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/LibwebsocketsConfig.cmake.in
  25. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/LibwebsocketsConfigVersion.cmake.in
  26. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/UseRPMTools.cmake
  27. 36 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/component.mk
  28. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/contrib/abi/README.md
  29. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/contrib/abi/libwebsockets.json
  30. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/contrib/abi/lws-abi-update.sh
  31. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/contrib/android-make-script.sh
  32. 32 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-aarch64.cmake
  33. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-arm-linux-gnueabihf.cmake
  34. 3 14
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-esp32.cmake
  35. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-ming.cmake
  36. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-openwrt-makefile
  37. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/doc-assets/lwsgt-overview.png
  38. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/.gitignore
  39. 83 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/alloc.c
  40. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/base64-decode.c
  41. 154 60
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/client-handshake.c
  42. 50 32
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/client-parser.c
  43. 134 24
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/client.c
  44. 219 55
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/context.c
  45. 43 38
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/daemonize.c
  46. 4 3
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/extension-permessage-deflate.c
  47. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/extension-permessage-deflate.h
  48. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/extension.c
  49. 669 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/fops-zip.c
  50. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/getifaddrs.c
  51. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/getifaddrs.h
  52. 7 2
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/handshake.c
  53. 14 15
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/header.c
  54. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/hpack.c
  55. 3 3
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/http2.c
  56. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/huftable.h
  57. 91 7
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lejp-conf.c
  58. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lejp.c
  59. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lejp.h
  60. 3 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lextable-strings.h
  61. 796 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lextable.h
  62. 11 5
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/libev.c
  63. 153 68
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/libuv.c
  64. 467 88
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/libwebsockets.c
  65. 476 149
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/libwebsockets.h
  66. 804 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-esp32.c
  67. 11 11
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-esp8266.c
  68. 322 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-optee.c
  69. 80 41
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-unix.c
  70. 77 44
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-win.c
  71. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/minihuf.c
  72. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/minilex.c
  73. 123 35
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/output.c
  74. 80 24
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/parsers.c
  75. 68 26
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/pollfd.c
  76. 165 81
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/private-libwebsockets.h
  77. 211 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ranges.c
  78. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/rewrite.c
  79. 216 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/romfs.c
  80. 63 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/romfs.h
  81. 102 33
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/server-handshake.c
  82. 468 146
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/server.c
  83. 255 60
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/service.c
  84. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/sha-1.c
  85. 3 1
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/smtp.c
  86. 176 89
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ssl-client.c
  87. 1 1
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ssl-http2.c
  88. 9 86
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ssl-server.c
  89. 135 232
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ssl.c
  90. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/libwebsockets.dox
  91. 10 2
      EVSE/GPL/libwebsockets-2.2.2-stable-org/libwebsockets.spec
  92. 19 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lws_config.h.in
  93. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lws_config_private.h.in
  94. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/etc-logrotate.d-lwsws
  95. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/etc-lwsws-conf-EXAMPLE
  96. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/etc-lwsws-conf.d-localhost-EXAMPLE
  97. 184 82
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/main.c
  98. 2 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/usr-lib-systemd-system-lwsws.service
  99. 4 1
      EVSE/GPL/libwebsockets-2.2.2-stable-org/mainpage.md
  100. 0 0
      EVSE/GPL/libwebsockets-2.2.2-stable-org/module.json

+ 6 - 6
EVSE/GPL/Makefile

@@ -6,16 +6,16 @@ export PATH=/bin:/sbin:/usr/bin:$(SDK_PATH_TARGET)usr/bin:usr/bin:$PATH
 all: libwebsocket Openssl ZIP30 BZIP2 DropBear WPA pppd Marvell8801 WirelessTool sqlite3 lighttpd libxml2 php pcre glibc json-c libpcap tcpdump can-utils iftop logrotate curl libmodbus
 
 libwebsocket :
-	echo "libwebsockets-v2.1-stable"
-	rm -rfv libwebsockets-v2.1-stable;cp -rfv libwebsockets-v2.1-stable-org libwebsockets-v2.1-stable;
-	cd libwebsockets-v2.1-stable;mkdir -p ./release;/usr/bin/cmake -DCMAKE_INSTALL_PREFIX:PATH=$(shell pwd)/libwebsockets-v2.1-stable/release \
+	echo "libwebsockets-2.2.2-stable"
+	rm -rfv libwebsockets-2.2.2-stable;cp -rfv libwebsockets-2.2.2-stable-org libwebsockets-2.2.2-stable;
+	cd libwebsockets-2.2.2-stable;mkdir -p ./release;/usr/bin/cmake -DCMAKE_INSTALL_PREFIX:PATH=$(shell pwd)/libwebsockets-2.2.2-stable/release \
  -DOPENSSL_ROOT_DIR=../openssl-1.0.2g/release -DCMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE=../openssl-1.0.2g/release \
  -DLWS_OPENSSL_INCLUDE_DIRS=../openssl-1.0.2g/release/include/openssl/ \
  -DLWS_OPENSSL_LIBRARIES="/opt/ti-processor-sdk-linux-am335x-evm-04.02.00.09/linux-devkit/sysroots/armv7ahf-neon-linux-gnueabi/usr/lib/libssl.so;/opt/ti-processor-sdk-linux-am335x-evm-04.02.00.09/linux-devkit/sysroots/armv7ahf-neon-linux-gnueabi/usr/lib/libcrypto.so" \
  -DCMAKE_TOOLCHAIN_FILE=./cross-arm-linux-gnueabihf.cmake -DWITHOUT_EXTENSIONS=1 -DWITH_SSL=1 -DCMAKE_BUILD_TYPE=DEBUG
-	make -C libwebsockets-v2.1-stable CC=$(CROSS_COMPILE)gcc
-	cd libwebsockets-v2.1-stable;make install
-	cp -f $(shell pwd)/libwebsockets-v2.1-stable/release/lib/libwebsockets.so.9 ../rootfs/lib
+	make -C libwebsockets-2.2.2-stable CC=$(CROSS_COMPILE)gcc
+	cd libwebsockets-2.2.2-stable;make install
+	cp -f $(shell pwd)/libwebsockets-2.2.2-stable/release/lib/libwebsockets.so.10 ../rootfs/lib
 
 ZIP30:
 	echo "zip30"

BIN
EVSE/GPL/libwebsockets-v2.1-stable-org.tgz → EVSE/GPL/libwebsockets-2.2.2-stable-org.tar.gz


+ 2 - 1
EVSE/GPL/libwebsockets-v2.1-stable/.gitignore → EVSE/GPL/libwebsockets-2.2.2-stable-org/.gitignore

@@ -1,5 +1,4 @@
 #Ignore build files
-Makefile
 config.h
 config.log
 config.status
@@ -23,6 +22,7 @@ win32port/zlib/Release*/
 *.suo
 *.su
 *.m4
+*.a
 missing
 depcomp
 install-sh
@@ -37,3 +37,4 @@ config.sub
 ar-lib
 libwebsockets.pc
 build/
+*.swp

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/.travis.yml → EVSE/GPL/libwebsockets-2.2.2-stable-org/.travis.yml


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/Android.mk → EVSE/GPL/libwebsockets-2.2.2-stable-org/Android.mk


+ 213 - 129
EVSE/GPL/libwebsockets-v2.1-stable/CMakeLists.txt → EVSE/GPL/libwebsockets-2.2.2-stable-org/CMakeLists.txt

@@ -9,12 +9,19 @@ project(libwebsockets C)
 set(PACKAGE "libwebsockets")
 set(CPACK_PACKAGE_NAME "${PACKAGE}")
 set(CPACK_PACKAGE_VERSION_MAJOR "2")
-set(CPACK_PACKAGE_VERSION_MINOR "1")
-set(CPACK_PACKAGE_VERSION_PATCH "0")
+set(CPACK_PACKAGE_VERSION_MINOR "2")
+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}")
-set(SOVERSION "9")
+set(SOVERSION "10")
+if(NOT CPACK_GENERATOR)
+    if(UNIX)
+        set(CPACK_GENERATOR "TGZ")
+    else()
+        set(CPACK_GENERATOR "ZIP")
+    endif()
+endif()
 set(CPACK_SOURCE_GENERATOR "TGZ")
 set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
 set(VERSION "${CPACK_PACKAGE_VERSION}")
@@ -62,6 +69,7 @@ endif()
 option(LWS_WITH_STATIC "Build the static version of the library" ON)
 option(LWS_WITH_SHARED "Build the shared version of the library" ON)
 option(LWS_WITH_SSL "Include SSL support (default OpenSSL, wolfSSL if LWS_USE_WOLFSSL is set)" ON)
+option(LWS_USE_BORINGSSL "Use BoringSSL replacement for OpenSSL" OFF)
 option(LWS_USE_CYASSL "Use CyaSSL replacement for OpenSSL. When setting this, you also need to specify LWS_CYASSL_LIBRARIES and LWS_CYASSL_INCLUDE_DIRS" OFF)
 option(LWS_USE_WOLFSSL "Use wolfSSL replacement for OpenSSL. When setting this, you also need to specify LWS_WOLFSSL_LIBRARIES and LWS_WOLFSSL_INCLUDE_DIRS" OFF)
 option(LWS_WITH_ZLIB "Include zlib support (required for extensions)" ON)
@@ -87,7 +95,6 @@ option(LWS_WITHOUT_DAEMONIZE "Don't build the daemonization api" ON)
 option(LWS_IPV6 "Compile with support for ipv6" OFF)
 option(LWS_UNIX_SOCK "Compile with support for UNIX domain socket" OFF)
 option(LWS_WITH_HTTP2 "Compile with support for http2" OFF)
-option(LWS_MBED3 "Platform is MBED3" OFF)
 option(LWS_SSL_SERVER_WITH_ECDH_CERT "Include SSL server use ECDH certificate" OFF)
 option(LWS_WITH_CGI "Include CGI (spawn process with network-connected stdin/out/err) APIs" OFF)
 option(LWS_WITH_HTTP_PROXY "Support for rewriting HTTP proxying" OFF)
@@ -101,8 +108,13 @@ option(LWS_WITH_GENERIC_SESSIONS "With the Generic Sessions plugin" OFF)
 option(LWS_WITH_SQLITE3 "Require SQLITE3 support" OFF)
 option(LWS_WITH_SMTP "Provide SMTP support" OFF)
 option(LWS_WITH_ESP8266 "Build for ESP8266" OFF)
+option(LWS_WITH_ESP32 "Build for ESP32" OFF)
+option(LWS_PLAT_OPTEE "Build for OPTEE" OFF)
 option(LWS_WITH_NO_LOGS "Disable all logging from being compiled in" OFF)
 option(LWS_STATIC_PIC "Build the static version of the library with position-independent code" OFF)
+option(LWS_WITH_RANGES "Support http ranges (RFC7233)" ON)
+option(LWS_FALLBACK_GETHOSTBYNAME "Also try to do dns resolution using gethostbyname if getaddrinfo fails" OFF)
+option(LWS_WITH_ZIP_FOPS "Support serving pre-zipped files" ON)
 
 if (LWS_WITH_LWSWS)
  message(STATUS "LWS_WITH_LWSWS --> Enabling LWS_WITH_PLUGINS and LWS_WITH_LIBUV")
@@ -134,21 +146,6 @@ message(STATUS "LWS_WITH_SMTP --> Enabling LWS_WITH_LIBUV")
  set(LWS_WITH_LIBUV 1)
 endif()
 
-if (DEFINED YOTTA_WEBSOCKETS_VERSION_STRING)
-
-set(LWS_WITH_SHARED OFF)
-set(LWS_WITH_SSL OFF)
-set(LWS_WITH_ZLIB OFF)
-set(LWS_WITHOUT_CLIENT ON)
-set(LWS_WITHOUT_TESTAPPS ON)
-set(LWS_WITHOUT_EXTENSIONS ON)
-set(LWS_WITH_PLUGINS OFF)
-set(LWS_MBED3 ON)
-# this implies no pthreads in the lib
-set(LWS_MAX_SMP 1)
-
-endif()
-
 if (LWS_WITH_ESP8266)
  set(LWS_WITH_SHARED OFF)
  set(LWS_WITH_SSL OFF)
@@ -157,11 +154,31 @@ if (LWS_WITH_ESP8266)
  set(LWS_WITHOUT_TESTAPPS ON)
  set(LWS_WITHOUT_EXTENSIONS ON)
  set(LWS_WITH_PLUGINS OFF)
+ set(LWS_WITH_RANGES OFF)
+ # this implies no pthreads in the lib
+ set(LWS_MAX_SMP 1)
+ set(LWS_HAVE_MALLOC 1)
+ set(LWS_HAVE_REALLOC 1)
+ set(LWS_HAVE_GETIFADDRS 1)
+ set(LWS_WITH_ZIP_FOPS 0)
+endif()
+
+if (LWS_WITH_ESP32)
+ set(LWS_WITH_SHARED OFF)
+ set(LWS_WITH_SSL OFF)
+ set(LWS_WITH_ZLIB OFF)
+ # set(LWS_WITHOUT_CLIENT ON)
+ set(LWS_WITHOUT_TESTAPPS ON)
+ set(LWS_WITHOUT_EXTENSIONS ON)
+ set(LWS_WITHOUT_CLIENT ON)
+ set(LWS_WITH_PLUGINS OFF)
+ set(LWS_WITH_RANGES ON)
  # this implies no pthreads in the lib
  set(LWS_MAX_SMP 1)
  set(LWS_HAVE_MALLOC 1)
  set(LWS_HAVE_REALLOC 1)
  set(LWS_HAVE_GETIFADDRS 1)
+ set(LWS_WITH_ZIP_FOPS 0)
 endif()
 
 
@@ -220,8 +237,8 @@ set( CACHE PATH "Path to the libev library")
 set(LWS_LIBEV_INCLUDE_DIRS CACHE PATH "Path to the libev include directory")
 set(LWS_LIBUV_LIBRARIES CACHE PATH "Path to the libuv library")
 set(LWS_LIBUV_INCLUDE_DIRS CACHE PATH "Path to the libuv include directory")
-set(LWS_SQLITE3_LIBRARIES CACHE PATH "Path to the libuv library")
-set(LWS_SQLITE3_INCLUDE_DIRS CACHE PATH "Path to the libuv include directory")
+set(LWS_SQLITE3_LIBRARIES CACHE PATH "Path to the sqlite3 library")
+set(LWS_SQLITE3_INCLUDE_DIRS CACHE PATH "Path to the sqlite3 include directory")
 
 
 if (NOT LWS_WITH_SSL)
@@ -231,7 +248,9 @@ endif()
 if (LWS_WITH_SSL AND NOT LWS_USE_WOLFSSL)
 	if ("${LWS_OPENSSL_LIBRARIES}" STREQUAL "" OR "${LWS_OPENSSL_INCLUDE_DIRS}" STREQUAL "")
 	else()
-		set(OPENSSL_LIBRARIES ${LWS_OPENSSL_LIBRARIES})
+		if (NOT LWS_WITH_ESP32)
+			set(OPENSSL_LIBRARIES ${LWS_OPENSSL_LIBRARIES})
+		endif()
 		set(OPENSSL_INCLUDE_DIRS ${LWS_OPENSSL_INCLUDE_DIRS})
 		set(OPENSSL_FOUND 1)
 	endif()
@@ -257,19 +276,6 @@ if (LWS_WITH_SSL AND LWS_USE_WOLFSSL)
 	endif()
 endif()
 
-if (LWS_WITH_SSL AND LWS_USE_MBEDTLS)
-	if ("${LWS_MBEDTLS_LIBRARIES}" STREQUAL "" OR "${LWS_MBEDTLS_INCLUDE_DIRS}" STREQUAL "")
-		if (NOT MBEDTLS_FOUND)
-			message(FATAL_ERROR "You must set LWS_MBEDTLS_LIBRARIES and LWS_MBEDTLS_INCLUDE_DIRS when LWS_USE_MBEDTLS is turned on.")
-		endif()
-	else()
-		set(MBEDTLS_LIBRARIES ${LWS_MBEDTLS_LIBRARIES})
-		set(MBEDTLS_INCLUDE_DIRS ${LWS_MBEDTLS_INCLUDE_DIRS})
-		set(MBEDTLS_FOUND 1)
-	endif()
-	set(USE_MBEDTLS 1)
-endif()
-
 if (LWS_WITH_ZLIB AND NOT LWS_USE_BUNDLED_ZLIB)
 	if ("${LWS_ZLIB_LIBRARIES}" STREQUAL "" OR "${LWS_ZLIB_INCLUDE_DIRS}" STREQUAL "")
 	else()
@@ -307,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")
@@ -381,9 +382,6 @@ endif()
 if (LWS_WITH_ESP8266)
 set(CMAKE_C_FLAGS "-nostdlib ${CMAKE_C_FLAGS}")
 endif()
-#if (LWS_MBED3)
-#	set(CMAKE_C_FLAGS "-D_DEBUG ${CMAKE_C_FLAGS}")
-#endif()
 
 if (MINGW)
 	set(LWS_MINGW_SUPPORT 1)
@@ -584,17 +582,23 @@ if (WIN32)
 	list(APPEND SOURCES
 		lib/lws-plat-win.c)
 else()
-	if (LWS_MBED3)
+
+	if (LWS_WITH_ESP8266)
 		list(APPEND SOURCES
-			lib/lws-plat-mbed3.cpp
-			lib/lws-plat-mbed3.c)
+			lib/lws-plat-esp8266.c)
 	else()
-		if (LWS_WITH_ESP8266)
+		if (LWS_PLAT_OPTEE)
 			list(APPEND SOURCES
-				lib/lws-plat-esp8266.c)
+				lib/lws-plat-optee.c)
 		else()
-			list(APPEND SOURCES
-				lib/lws-plat-unix.c)
+			if (LWS_WITH_ESP32)
+				list(APPEND SOURCES
+					lib/lws-plat-esp32.c
+					lib/romfs.c)
+			else()
+				list(APPEND SOURCES
+					lib/lws-plat-unix.c)
+			endif()
 		endif()
 	endif()
 endif()
@@ -645,6 +649,20 @@ if (LWS_WITH_SMTP)
 		lib/smtp.c)
 endif()
 
+if (LWS_WITH_RANGES)
+	list(APPEND SOURCES
+		lib/ranges.c)
+endif()
+
+if (LWS_WITH_ZIP_FOPS)
+       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.
 if (WIN32)
 	set(WIN32_HELPERS_PATH win32port/win32helpers)
@@ -727,6 +745,17 @@ if (LWS_WITH_STATIC)
 			PROPERTIES
 			OUTPUT_NAME websockets_static)
 	endif()
+	add_custom_command(
+		      TARGET websockets
+		      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_CURRENT_BINARY_DIR}/lws_config.h
+		     					 ${CMAKE_CURRENT_BINARY_DIR}/include/lws_config.h
+	)
+
 endif()
 
 if (LWS_WITH_SHARED)
@@ -754,6 +783,19 @@ if (LWS_WITH_SHARED)
 	if (APPLE)
 		set_property(TARGET websockets_shared PROPERTY MACOSX_RPATH YES)
 	endif()
+
+	add_custom_command(
+		      TARGET websockets_shared
+		      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_CURRENT_BINARY_DIR}/lws_config.h
+		     					 ${CMAKE_CURRENT_BINARY_DIR}/include/lws_config.h
+	)
+
+
 endif()
 
 # Set the so version of the lib.
@@ -847,17 +889,23 @@ if (LWS_WITH_SSL)
 	endif()
 
 	if (NOT chose_ssl)
-		if (NOT OPENSSL_FOUND)
+		if (NOT OPENSSL_FOUND AND NOT LWS_USE_BORINGSSL)
 			# TODO: Add support for STATIC also.
+		if (NOT LWS_WITH_ESP32)
 			find_package(OpenSSL REQUIRED)
+		endif()
 			set(OPENSSL_INCLUDE_DIRS "${OPENSSL_INCLUDE_DIR}")
 		endif()
 
 		message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIRS}")
-		message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
+		if (NOT LWS_WITH_ESP32)
+			message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
+		endif()
 
 		include_directories("${OPENSSL_INCLUDE_DIRS}")
-		list(APPEND LIB_LIST ${OPENSSL_LIBRARIES})
+		if (NOT LWS_WITH_ESP32)
+			list(APPEND LIB_LIST ${OPENSSL_LIBRARIES})
+		endif()
 
 	# older (0.98) Openssl lacks this
 	set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
@@ -925,7 +973,7 @@ endif()
 if (WINCE)
 	list(APPEND LIB_LIST ws2.lib)
 elseif (WIN32)
-	list(APPEND LIB_LIST ws2_32.lib)
+	list(APPEND LIB_LIST ws2_32.lib userenv.lib psapi.lib iphlpapi.lib)
 endif()
 
 if (UNIX)
@@ -941,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(
@@ -952,6 +1002,93 @@ configure_file(
        "${PROJECT_SOURCE_DIR}/lws_config_private.h.in"
        "${PROJECT_BINARY_DIR}/lws_config_private.h")
 
+# Generate self-signed SSL certs for the test-server.
+
+if (LWS_WITH_SSL AND NOT LWS_USE_WOLFSSL)
+	message("Searching for OpenSSL executable and dlls")
+	find_package(OpenSSLbins)
+	message("OpenSSL executable: ${OPENSSL_EXECUTABLE}")
+	if (OPENSSL_EXECUTABLE MATCHES "^$")
+		set(OPENSSL_EXECUTABLE openssl)
+	endif()
+	if (NOT OPENSSL_EXECUTABLE)
+		set(OPENSSL_EXECUTABLE openssl)
+	endif()
+
+endif()
+
+set(GENCERTS 0)
+
+if (LWS_WITH_SSL AND OPENSSL_EXECUTABLE AND NOT LWS_WITHOUT_TEST_SERVER)
+	set(GENCERTS 1)
+endif()
+if (LWS_WITH_ESP32)
+	set(GENCERTS 1)
+endif()
+message(" GENCERTS = ${GENCERTS}")
+if (GENCERTS)
+	message("Generating SSL Certificates for the test-server...")
+
+	set(TEST_SERVER_SSL_KEY "${PROJECT_BINARY_DIR}/libwebsockets-test-server.key.pem")
+	set(TEST_SERVER_SSL_CERT "${PROJECT_BINARY_DIR}/libwebsockets-test-server.pem")
+
+	if (WIN32)
+		if (MINGW)
+			message("cmd = \"${OPENSSL_EXECUTABLE}\" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -subj \"/C=GB/ST=Erewhon/L=All around/O=libwebsockets-test/CN=localhost\" -keyout \"${TEST_SERVER_SSL_KEY}\" -out \"${TEST_SERVER_SSL_CERT}\"")
+			execute_process(
+				COMMAND "${OPENSSL_EXECUTABLE}" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -subj "/C=GB/ST=Erewhon/L=All around/O=libwebsockets-test/CN=localhost" -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
+				RESULT_VARIABLE OPENSSL_RETURN_CODE)
+		else()
+			file(WRITE "${PROJECT_BINARY_DIR}/openssl_input.txt"
+				"GB\n"
+				"Erewhon\n"
+				"All around\n"
+				"libwebsockets-test\n"
+				"localhost\n"
+				"none@invalid.org\n\n"
+				)
+
+			# The "type" command is a bit picky with paths.
+			file(TO_NATIVE_PATH "${PROJECT_BINARY_DIR}/openssl_input.txt" OPENSSL_INPUT_WIN_PATH)
+			message("OPENSSL_INPUT_WIN_PATH = ${OPENSSL_INPUT_WIN_PATH}")
+			message("cmd = \"${OPENSSL_EXECUTABLE}\" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout \"${TEST_SERVER_SSL_KEY}\" -out \"${TEST_SERVER_SSL_CERT}\"")
+
+			execute_process(
+				COMMAND cmd /c type "${OPENSSL_INPUT_WIN_PATH}"
+				COMMAND "${OPENSSL_EXECUTABLE}" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
+				RESULT_VARIABLE OPENSSL_RETURN_CODE
+				OUTPUT_QUIET ERROR_QUIET)
+
+			message("\n")
+		endif()
+
+		if (OPENSSL_RETURN_CODE)
+			message(WARNING "!!! Failed to generate SSL certificate for Test Server using cmd.exe !!!:\nOpenSSL return code = ${OPENSSL_RETURN_CODE}")
+		else()
+			message("SUCCSESFULLY generated SSL certificate")
+		endif()
+	else()
+		# Unix.
+		execute_process(
+			COMMAND printf "GB\\nErewhon\\nAll around\\nlibwebsockets-test\\n\\nlocalhost\\nnone@invalid.org\\n"
+			COMMAND "${OPENSSL_EXECUTABLE}"
+				req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
+			RESULT_VARIABLE OPENSSL_RETURN_CODE
+			OUTPUT_QUIET ERROR_QUIET)
+
+		if (OPENSSL_RETURN_CODE)
+			message(WARNING "!!! Failed to generate SSL certificate for Test Server!!!:\nOpenSSL return code = ${OPENSSL_RETURN_CODE}")
+		else()
+			message("SUCCESSFULLY generated SSL certificate")
+		endif()
+	endif()
+
+	list(APPEND TEST_SERVER_DATA 
+		"${TEST_SERVER_SSL_KEY}"
+		"${TEST_SERVER_SSL_CERT}")
+endif()
+
+
 
 
 #
@@ -1032,17 +1169,16 @@ if (NOT LWS_WITHOUT_TESTAPPS)
 		list(APPEND TEST_APP_LIST ${TEST_NAME})
 	endmacro()
 
-	if (LWS_WITH_SSL AND NOT LWS_USE_WOLFSSL)
-		message("Searching for OpenSSL executable and dlls")
-		find_package(OpenSSLbins)
-		message("OpenSSL executable: ${OPENSSL_EXECUTABLE}")
-	endif()
-
 	if (UNIX AND LWS_WITH_PLUGINS)
 		set(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
-		target_link_libraries(websockets dl)
+		if(NOT(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD"))
+			target_link_libraries(websockets dl)
+		endif()
 	endif()
 
+
+
+
 	if (NOT LWS_WITHOUT_SERVER)
 		#
 		# test-server
@@ -1135,73 +1271,11 @@ if (NOT LWS_WITHOUT_TESTAPPS)
 		set(TEST_SERVER_DATA
 			"${PROJECT_SOURCE_DIR}/test-server/favicon.ico"
 			"${PROJECT_SOURCE_DIR}/test-server/leaf.jpg"
+			"${PROJECT_SOURCE_DIR}/test-server/candide.zip"
 			"${PROJECT_SOURCE_DIR}/test-server/libwebsockets.org-logo.png"
 			"${PROJECT_SOURCE_DIR}/test-server/lws-common.js"
 			"${PROJECT_SOURCE_DIR}/test-server/test.html")
 
-		# Generate self-signed SSL certs for the test-server.
-		if (LWS_WITH_SSL AND OPENSSL_EXECUTABLE AND NOT LWS_WITHOUT_TEST_SERVER)
-			message("Generating SSL Certificates for the test-server...")
-
-			set(TEST_SERVER_SSL_KEY "${PROJECT_BINARY_DIR}/libwebsockets-test-server.key.pem")
-			set(TEST_SERVER_SSL_CERT "${PROJECT_BINARY_DIR}/libwebsockets-test-server.pem")
-
-			if (WIN32)
-				if (MINGW)
-					message("cmd = \"${OPENSSL_EXECUTABLE}\" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -subj \"/C=GB/ST=Erewhon/L=All around/O=libwebsockets-test/CN=localhost\" -keyout \"${TEST_SERVER_SSL_KEY}\" -out \"${TEST_SERVER_SSL_CERT}\"")
-					execute_process(
-						COMMAND "${OPENSSL_EXECUTABLE}" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -subj "/C=GB/ST=Erewhon/L=All around/O=libwebsockets-test/CN=localhost" -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
-						RESULT_VARIABLE OPENSSL_RETURN_CODE)
-				else()
-					file(WRITE "${PROJECT_BINARY_DIR}/openssl_input.txt"
-						"GB\n"
-						"Erewhon\n"
-						"All around\n"
-						"libwebsockets-test\n"
-						"localhost\n"
-						"none@invalid.org\n\n"
-						)
-
-					# The "type" command is a bit picky with paths.
-					file(TO_NATIVE_PATH "${PROJECT_BINARY_DIR}/openssl_input.txt" OPENSSL_INPUT_WIN_PATH)
-					message("OPENSSL_INPUT_WIN_PATH = ${OPENSSL_INPUT_WIN_PATH}")
-					message("cmd = \"${OPENSSL_EXECUTABLE}\" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout \"${TEST_SERVER_SSL_KEY}\" -out \"${TEST_SERVER_SSL_CERT}\"")
-
-					execute_process(
-						COMMAND cmd /c type "${OPENSSL_INPUT_WIN_PATH}"
-						COMMAND "${OPENSSL_EXECUTABLE}" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
-						RESULT_VARIABLE OPENSSL_RETURN_CODE
-						OUTPUT_QUIET ERROR_QUIET)
-
-					message("\n")
-				endif()
-
-				if (OPENSSL_RETURN_CODE)
-					message(WARNING "!!! Failed to generate SSL certificate for Test Server using cmd.exe !!!:\nOpenSSL return code = ${OPENSSL_RETURN_CODE}")
-				else()
-					message("SUCCSESFULLY generated SSL certificate")
-				endif()
-			else()
-				# Unix.
-				execute_process(
-					COMMAND printf "GB\\nErewhon\\nAll around\\nlibwebsockets-test\\n\\nlocalhost\\nnone@invalid.org\\n"
-					COMMAND "${OPENSSL_EXECUTABLE}"
-						req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
-					RESULT_VARIABLE OPENSSL_RETURN_CODE
-					OUTPUT_QUIET ERROR_QUIET)
-
-				if (OPENSSL_RETURN_CODE)
-					message(WARNING "!!! Failed to generate SSL certificate for Test Server!!!:\nOpenSSL return code = ${OPENSSL_RETURN_CODE}")
-				else()
-					message("SUCCESSFULLY generated SSL certificate")
-				endif()
-			endif()
-
-			list(APPEND TEST_SERVER_DATA 
-				"${TEST_SERVER_SSL_KEY}"
-				"${TEST_SERVER_SSL_CERT}")
-		endif()
-
 		add_custom_command(TARGET test-server
 						POST_BUILD 
 						COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:test-server>/../share/libwebsockets-test-server")
@@ -1307,6 +1381,10 @@ if (NOT LWS_WITHOUT_TESTAPPS)
 			      "plugins/protocol_post_demo.c" "" "")
 		create_plugin(protocol_lws_table_dirlisting
 			      "plugins/generic-table/protocol_table_dirlisting.c" "" "")
+		if (NOT WIN32)
+      		      create_plugin(protocol_lws_raw_test
+			      "plugins/protocol_lws_raw_test.c" "" "")
+		endif()
 
 if (LWS_WITH_SERVER_STATUS)
 		create_plugin(protocol_lws_server_status
@@ -1503,6 +1581,10 @@ endif()
 if (NOT LWS_WITHOUT_TESTAPPS AND NOT LWS_WITHOUT_SERVER)
 	install(FILES ${TEST_SERVER_DATA}
 			DESTINATION share/libwebsockets-test-server
+		COMPONENT examples)
+
+		install(FILES "${PROJECT_SOURCE_DIR}/test-server/private/index.html"
+			DESTINATION share/libwebsockets-test-server/private
 			COMPONENT examples)
 if (LWS_WITH_CGI)
 	set(CGI_TEST_SCRIPT "${PROJECT_SOURCE_DIR}/test-server/lws-cgi-test.sh")
@@ -1611,7 +1693,6 @@ message(" LWS_USE_LIBUV = ${LWS_USE_LIBUV}")
 message(" LWS_IPV6 = ${LWS_IPV6}")
 message(" LWS_UNIX_SOCK = ${LWS_UNIX_SOCK}")
 message(" LWS_WITH_HTTP2 = ${LWS_WITH_HTTP2}")
-message(" LWS_MBED3 = ${LWS_MBED3}")
 message(" LWS_SSL_SERVER_WITH_ECDH_CERT = ${LWS_SSL_SERVER_WITH_ECDH_CERT}")
 message(" LWS_MAX_SMP = ${LWS_MAX_SMP}")
 message(" LWS_WITH_CGI = ${LWS_WITH_CGI}")
@@ -1627,14 +1708,17 @@ message(" LWS_WITH_LEJP_CONF = ${LWS_WITH_LEJP_CONF}")
 message(" LWS_WITH_SMTP = ${LWS_WITH_SMTP}")
 message(" LWS_WITH_GENERIC_SESSIONS = ${LWS_WITH_GENERIC_SESSIONS}")
 message(" LWS_STATIC_PIC = ${LWS_STATIC_PIC}")
-
+message(" LWS_WITH_RANGES = ${LWS_WITH_RANGES}")
+message(" LWS_PLAT_OPTEE = ${LWS_PLAT_OPTEE}")
+message(" LWS_WITH_ESP32 = ${LWS_WITH_ESP32}")
+message(" LWS_WITH_ZIP_FOPS = ${LWS_WITH_ZIP_FOPS}")
 
 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")

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/FindLibWebSockets.cmake → EVSE/GPL/libwebsockets-2.2.2-stable-org/FindLibWebSockets.cmake


+ 9 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/Kconfig

@@ -0,0 +1,9 @@
+menu "Libwebsockets"
+
+config LWS
+    bool "Enable Libwebsockets"
+    default n
+    help
+       Enable Libwebsockets Library
+
+endmenu

+ 12 - 4
EVSE/GPL/libwebsockets-v2.1-stable/LICENSE → EVSE/GPL/libwebsockets-2.2.2-stable-org/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
 

+ 46 - 42
EVSE/GPL/libwebsockets-v2.1-stable-org/README.build.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/README.build.md

@@ -13,7 +13,7 @@ create elaborate clean scripts to get a clean source tree, instead you
 simply remove your build directory.
 
 Libwebsockets has been tested to build successfully on the following platforms
-with SSL support (both OpenSSL/wolfSSL):
+with SSL support (for OpenSSL/wolfSSL/BoringSSL):
 
 - Windows (Visual Studio)
 - Windows (MinGW)
@@ -93,6 +93,14 @@ To get it to build on latest openssl (2016-04-10) it needed this approach
 	cmake .. -DLWS_WITH_HTTP2=1 -DLWS_OPENSSL_INCLUDE_DIRS=/usr/local/include/openssl -DLWS_OPENSSL_LIBRARIES="/usr/local/lib64/libssl.so;/usr/local/lib64/libcrypto.so"
 ```
 
+Mac users have reported
+
+```
+ $ export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2k; cmake ..; make -j4
+```
+
+worked for them when using "homebrew" OpenSSL
+
 **NOTE5**:
 To build with debug info and _DEBUG for lower priority debug messages
 compiled in, use
@@ -168,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)
 
@@ -184,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
 
@@ -223,51 +239,19 @@ cmake from scratch.
 	$ make install
 ```
 
-@section mbed3 Building on mbed3
-
-MBED3 is a non-posix embedded OS targeted on Cortex M class chips.
-
-https://www.mbed.com/
-
-It's quite unlike any other Posixy platform since the OS is linked statically
-in with lws to form one binary.
-
-At the minute server-only is supported and due to bugs in mbed3 network support,
-the port is of alpha quality.  However it can serve the test html, favicon.ico
-and logo png and may be able to make ws connections.  The binary for that
-including the OS, test app, lws and all the assets is only 117KB.
-
-0) Today mbed3 only properly works on FRDM K64F $35 Freescale Dev Board with
-1MB Flash, 256KB SRAM and Ethernet.
-
-http://www.freescale.com/products/arm-processors/kinetis-cortex-m/k-series/k6x-ethernet-mcus/freescale-freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F
-
-1) Get a working mbed3 environment with arm-none-eabi-cs toolchain
-(available in Fedora, Ubuntu and other distros)
-
-2) Confirm you can build things using yotta by following the getting started guide here
+@section optee Building for OP-TEE
 
-https://docs.mbed.com/docs/getting-started-mbed-os/en/latest/
+OP-TEE is a "Secure World" Trusted Execution Environment.
 
-3)
+Although lws is only part of the necessary picture to have an https-enabled
+TA, it does support OP-TEE as a platform and if you provide the other
+pieces, does work very well.
 
-git clone https://github.com/warmcat/lws-test-server
+Select it in cmake with `-DLWS_PLAT_OPTEE=1`
 
-and cd into it
-
-4) mkdir -p yotta_modules ; cd yotta_modules
-
-5) git clone https://github.com/warmcat/libwebsockets ; mv libwebsockets websockets ; cd ..
-
-6) yotta target frdm-k64f-gcc
-
-7) yotta install
-
-8) yotta build
 
 @section cmco Setting compile options
 
-
 To set compile time flags you can either use one of the CMake gui applications
 or do it via the command line.
 
@@ -327,6 +311,26 @@ this to work.
 
 **NOTE**: On windows use the .lib file extension for `LWS_CYASSL_LIBRARIES` instead.
 
+@section esp32 Building for ESP32
+
+Step 1, get ESP-IDF with lws integrated as a component
+
+```
+    $ git clone --int --recursive https://github.com/lws-team/lws-esp-idf
+```
+
+Step 2: Get Application including the test plugins
+
+```
+    $ git clone https://github.com/lws-team/lws-esp32
+```
+
+Set your IDF_PATH to point to the esp-idf you downloaded in 1)
+
+There's docs for how to build the lws-esp32 test app and reproduce it in the README.md here
+
+https://github.com/lws-team/lws-esp32/blob/master/README.md
+
 
 @section extplugins Building plugins outside of lws itself
 
@@ -395,7 +399,7 @@ The commandline to configure for cross with this would look like
 ```
 	$ cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/usr \
 		 -DCMAKE_TOOLCHAIN_FILE=../cross-arm-linux-gnueabihf.cmake \
-		 -DWITHOUT_EXTENSIONS=1 -DWITH_SSL=0
+		 -DLWS_WITHOUT_EXTENSIONS=1 -DLWS_WITH_SSL=0
 ```
 The example shows how to build with no external cross lib dependencies, you
 need to provide the cross libraries otherwise.

+ 200 - 10
EVSE/GPL/libwebsockets-v2.1-stable-org/README.coding.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/README.coding.md

@@ -120,6 +120,34 @@ the send pipe on the connection is choked but no ack will ever come, so the
 dead connection will never become writeable.  To cover that, you can use TCP
 keepalives (see later in this document) or pings.
 
+@section gzip Serving from inside a zip file
+
+Lws now supports serving gzipped files from inside a zip container.  Thanks to
+Per Bothner for contributing the code.
+
+This has the advtantage that if the client can accept GZIP encoding, lws can
+simply send the gzip-compressed file from inside the zip file with no further
+processing, saving time and bandwidth.
+
+In the case the client can't understand gzip compression, lws automatically
+decompressed the file and sends it normally.
+
+Clients with limited storage and RAM will find this useful; the memory needed
+for the inflate case is constrained so that only one input buffer at a time
+is ever in memory.
+
+To use this feature, ensure LWS_WITH_ZIP_FOPS is enabled at CMake (it is by
+default).
+
+`libwebsockets-test-server-v2.0` includes a mount using this technology
+already, run that test server and navigate to http://localhost:7681/ziptest/candide.html
+
+This will serve the book Candide in html, together with two jpgs, all from
+inside a .zip file in /usr/[local/]share-libwebsockets-test-server/candide.zip
+
+Usage is otherwise automatic, if you arrange a mount that points to the zipfile,
+eg, "/ziptest" -> "mypath/test.zip", then URLs like `/ziptest/index.html` will be
+servied from `index.html` inside `mypath/test.zip`
 
 @section frags Fragmented messages
 
@@ -347,25 +375,187 @@ and then can use helpers to also leverage these platform-independent
 file handling apis
 
 ```
-	static inline lws_filefd_type
-	`lws_plat_file_open`(struct lws *wsi, const char *filename, unsigned long *filelen, int flags)
+	lws_fop_fd_t
+	`lws_plat_file_open`(struct lws_plat_file_ops *fops, const char *filename,
+			   lws_fop_flags_t *flags)
+	int
+	`lws_plat_file_close`(lws_fop_fd_t fop_fd)
+
+	unsigned long
+	`lws_plat_file_seek_cur`(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
+
+	int
+	`lws_plat_file_read`(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+		   uint8_t *buf, lws_filepos_t len)
+
+	int
+	`lws_plat_file_write`(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+		   uint8_t *buf, lws_filepos_t len )
+```
 
-	static inline int
-	`lws_plat_file_close`(struct lws *wsi, lws_filefd_type fd)
+Generic helpers are provided which provide access to generic fops information or
+call through to the above fops
 
-	static inline unsigned long
-	`lws_plat_file_seek_cur`(struct lws *wsi, lws_filefd_type fd, long offset_from_cur_pos)
+```
+lws_filepos_t
+lws_vfs_tell(lws_fop_fd_t fop_fd);
 
-	static inline int
-	`lws_plat_file_read`(struct lws *wsi, lws_filefd_type fd, unsigned long *amount, unsigned char *buf, unsigned long len)
+lws_filepos_t
+lws_vfs_get_length(lws_fop_fd_t fop_fd);
 
-	static inline int
-	`lws_plat_file_write`(struct lws *wsi, lws_filefd_type fd, unsigned long *amount, unsigned char *buf, unsigned long len)
+uint32_t
+lws_vfs_get_mod_time(lws_fop_fd_t fop_fd);
+
+lws_fileofs_t
+lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset);
+
+lws_fileofs_t
+lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset);
 ```
 
+
 The user code can also override or subclass the file operations, to either
 wrap or replace them.  An example is shown in test server.
 
+### Changes from v2.1 and before fops
+
+There are several changes:
+
+1) Pre-2.2 fops directly used platform file descriptors.  Current fops returns and accepts a wrapper type lws_fop_fd_t which is a pointer to a malloc'd struct containing information specific to the filesystem implementation.
+
+2) Pre-2.2 fops bound the fops to a wsi.  This is completely removed, you just give a pointer to the fops struct that applies to this file when you open it.  Afterwards, the operations in the fops just need the lws_fop_fd_t returned from the open.
+
+3) Everything is wrapped in typedefs.  See lws-plat-unix.c for examples of how to implement.
+
+4) Position in the file, File Length, and a copy of Flags left after open are now generically held in the fop_fd.
+VFS implementation must set and manage this generic information now.  See the implementations in lws-plat-unix.c for
+examples.
+
+5) The file length is no longer set at a pointer provided by the open() fop.  The api `lws_vfs_get_length()` is provided to
+get the file length after open.
+
+6) If your file namespace is virtual, ie, is not reachable by platform fops directly, you must set LWS_FOP_FLAG_VIRTUAL
+on the flags during open.
+
+7) There is an optional `mod_time` uint32_t member in the generic fop_fd.  If you are able to set it during open, you
+should indicate it by setting `LWS_FOP_FLAG_MOD_TIME_VALID` on the flags.
+
+@section rawfd RAW file descriptor polling
+
+LWS allows you to include generic platform file descriptors in the lws service / poll / event loop.
+
+Open your fd normally and then
+
+```
+	lws_sock_file_fd_type u;
+
+	u.filefd = your_open_file_fd;
+
+	if (!lws_adopt_descriptor_vhost(vhost, 0, u,
+					"protocol-name-to-bind-to",
+					optional_wsi_parent_or_NULL)) {
+		// failed
+	}
+
+	// OK
+```
+
+A wsi is created for the file fd that acts like other wsi, you will get these
+callbacks on the named protocol
+
+```
+	LWS_CALLBACK_RAW_ADOPT_FILE
+	LWS_CALLBACK_RAW_RX_FILE
+	LWS_CALLBACK_RAW_WRITEABLE_FILE
+	LWS_CALLBACK_RAW_CLOSE_FILE
+```
+
+starting with LWS_CALLBACK_RAW_ADOPT_FILE.
+
+`protocol-lws-raw-test` plugin provides a method for testing this with
+`libwebsockets-test-server-v2.0`:
+
+The plugin creates a FIFO on your system called "/tmp/lws-test-raw"
+
+You can feed it data through the FIFO like this
+
+```
+  $ sudo sh -c "echo hello > /tmp/lws-test-raw"
+```
+
+This plugin simply prints the data.  But it does it through the lws event
+loop / service poll.
+
+@section rawsrvsocket RAW server socket descriptor polling
+
+You can also enable your vhost to accept RAW socket connections, in addition to
+HTTP[s] and WS[s].  If the first bytes written on the connection are not a
+valid HTTP method, then the connection switches to RAW mode.
+
+This is disabled by default, you enable it by setting the `.options` flag
+LWS_SERVER_OPTION_FALLBACK_TO_RAW when creating the vhost.
+
+RAW mode socket connections receive the following callbacks
+
+```
+	LWS_CALLBACK_RAW_ADOPT
+	LWS_CALLBACK_RAW_RX
+	LWS_CALLBACK_RAW_WRITEABLE
+	LWS_CALLBACK_RAW_CLOSE
+```
+
+You can control which protocol on your vhost handles these RAW mode
+incoming connections by marking the selected protocol with a pvo `raw`, eg
+
+```
+        "protocol-lws-raw-test": {
+                 "status": "ok",
+                 "raw": "1"
+        },
+```
+
+The "raw" pvo marks this protocol as being used for RAW connections.
+
+`protocol-lws-raw-test` plugin provides a method for testing this with
+`libwebsockets-test-server-v2.0`:
+
+Run libwebsockets-test-server-v2.0 and connect to it by telnet, eg
+
+```
+    $ telnet 127.0.0.1 7681
+```
+
+type something that isn't a valid HTTP method and enter, before the
+connection times out.  The connection will switch to RAW mode using this
+protocol, and pass the unused rx as a raw RX callback.
+    
+The test protocol echos back what was typed on telnet to telnet.
+
+@section rawclientsocket RAW client socket descriptor polling
+
+You can now also open RAW socket connections in client mode.
+
+Follow the usual method for creating a client connection, but set the
+`info.method` to "RAW".  When the connection is made, the wsi will be
+converted to RAW mode and operate using the same callbacks as the
+server RAW sockets described above.
+
+The libwebsockets-test-client supports this using raw:// URLS.  To
+test, open a netcat listener in one window
+
+```
+ $ nc -l 9999
+```
+
+and in another window, connect to it using the test client
+
+```
+ $ libwebsockets-test-client raw://127.0.0.1:9999
+```
+
+The connection should succeed, and text typed in the netcat window (including a CRLF)
+will be received in the client.
+
 @section ecdh ECDH Support
 
 ECDH Certs are now supported.  Enable the CMake option

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/README.esp8266.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/README.esp8266.md


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/README.generic-sessions.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/README.generic-sessions.md


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/README.generic-table.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/README.generic-table.md


+ 111 - 12
EVSE/GPL/libwebsockets-v2.1-stable/README.lwsws.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/README.lwsws.md

@@ -79,6 +79,20 @@ on port 7681, non-SSL is provided.  To set it up
 	# sudo lwsws
 ```
 
+@section lwsogo Other Global Options
+
+ - `reject-service-keywords` allows you to return an HTTP error code and message of your choice
+if a keyword is found in the user agent
+
+```
+   "reject-service-keywords": [{
+        "scumbot": "404 Not Found"
+   }]
+```
+
+ - `timeout-secs` lets you set the global timeout for various network-related
+ operations in lws, in seconds.  It defaults to 5.
+ 
 @section lwswsv Lwsws Vhosts
 
 One server can run many vhosts, where SSL is in use SNI is used to match
@@ -359,6 +373,36 @@ If you provide an extra mimetype entry
 Then any file is served, if the mimetype was not known then it is served without a
 Content-Type: header.
 
+7) A mount can be protected by HTTP Basic Auth.  This only makes sense when using
+https, since otherwise the password can be sniffed.
+
+You can add a `basic-auth` entry on a mount like this
+
+```
+{
+        "mountpoint": "/basic-auth",
+        "origin": "file://_lws_ddir_/libwebsockets-test-server/private",
+        "basic-auth": "/var/www/balogins-private"
+}
+```
+
+Before serving anything, lws will signal to the browser that a username / password
+combination is required, and it will pop up a dialog.  When the user has filled it
+in, lwsws checks the user:password string against the text file named in the `basic-auth`
+entry.
+
+The file should contain user:pass one per line
+
+```
+testuser:testpass
+myuser:hispass
+```
+
+The file should be readable by lwsws, and for a little bit of extra security not
+have a file suffix, so lws would reject to serve it even if it could find it on
+a mount.
+
+
 @section lwswspl Lwsws Plugins
 
 Protcols and extensions may also be provided from "plugins", these are
@@ -410,7 +454,7 @@ Enable the protocol like this on a vhost's ws-protocols section
 	         "update-ms": "5000"
 	       }
 ```
-"update-ms" is used to control how often updated JSON is sent on a ws link.
+`"update-ms"` is used to control how often updated JSON is sent on a ws link.
 
 And map the provided HTML into the vhost in the mounts section
 ```
@@ -421,23 +465,78 @@ And map the provided HTML into the vhost in the mounts section
 	       }
 ```
 You might choose to put it on its own vhost which has "interface": "lo", so it's not
-externally visible.
+externally visible, or use the Basic Auth support to require authentication to
+access it.
+
+`"hide-vhosts": "{0 | 1}"` lets you control if information about your vhosts is included.
+Since this includes mounts, you might not want to leak that information, mount names,
+etc.
+
+`"filespath":"{path}"` lets you give a server filepath which is read and sent to the browser
+on each refresh.  For example, you can provide server temperature information on most
+Linux systems by giving an appropriate path down /sys.
 
+This may be given multiple times.
+
+
+@section lwswsreload Lwsws Configuration Reload
+
+You may send lwsws a `HUP` signal, by, eg
+
+```
+$ sudo killall -HUP lwsws
+```
+
+This causes lwsws to "deprecate" the existing lwsws process, and remove and close all of
+its listen sockets, but otherwise allowing it to continue to run, until all
+of its open connections close.
+
+When a deprecated lwsws process has no open connections left, it is destroyed
+automatically.
+
+After sending the SIGHUP to the main lwsws process, a new lwsws process, which can
+pick up the newly-available listen sockets, and use the current configuration
+files, is automatically started.
+
+The new configuration may differ from the original one in arbitrary ways, the new
+context is created from scratch each time without reference to the original one.
+
+Notes
+
+1) Protocols that provide a "shared world" like mirror will have as many "worlds"
+as there are lwsws processes still active.  People connected to a deprecated lwsws
+process remain connected to the existing peers.
+
+But any new connections will apply to the new lwsws process, which does not share
+per-vhost "shared world" data with the deprecated process.  That means no new
+connections on the deprecated context, ie a "shrinking world" for those guys, and a
+"growing world" for people who connect after the SIGHUP.
+
+2) The new lwsws process owes nothing to the previous one.  It starts with fresh
+plugins, fresh configuration, fresh root privileges if that how you start it.
+
+The plugins may have been updated in arbitrary ways including struct size changes
+etc, and lwsws or lws may also have been updated arbitrarily.
+
+3) A root parent process is left up that is not able to do anything except
+respond to SIGHUP or SIGTERM.  Actual serving and network listening etc happens
+in child processes which use the privileges set in the lwsws config files.
 
 @section lwswssysd Lwsws Integration with Systemd
 
 lwsws needs a service file like this as `/usr/lib/systemd/system/lwsws.service`
 ```
-	[Unit]
-	Description=Libwebsockets Web Server
-	After=syslog.target
-	
-	[Service]
-	ExecStart=/usr/local/bin/lwsws
-	StandardError=null
-	
-	[Install]
-	WantedBy=multi-user.target
+[Unit]
+Description=Libwebsockets Web Server
+After=syslog.target
+
+[Service]
+ExecStart=/usr/local/bin/lwsws 
+ExecReload=/usr/bin/killall -s SIGHUP lwsws ; sleep 1 ; /usr/local/bin/lwsws
+StandardError=null
+
+[Install]
+WantedBy=multi-user.target
 ```
 
 You can find this prepared in `./lwsws/usr-lib-systemd-system-lwsws.service`

+ 2 - 2
EVSE/GPL/libwebsockets-v2.1-stable-org/README.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/README.md

@@ -7,8 +7,8 @@ libwebsockets
 
 | News |
 ------
-| ESP8266 is now supported in lws!  See https://github.com/warmcat/libwebsockets/blob/master/README.esp8266.md |
-
+| ESP32 is now supported in lws!  https://libwebsockets.org/lws-api-doc-master/html/md_README_8build.html |
+| v2.2 is out... see the changelog https://github.com/warmcat/libwebsockets/blob/v2.2-stable/changelog |
 
 This is the libwebsockets C library for lightweight websocket clients and
 servers.  For support, visit

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/README.problems.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/README.problems.md


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/README.test-apps.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/README.test-apps.md


+ 5 - 3
EVSE/GPL/libwebsockets-v2.1-stable-org/appveyor.yml → EVSE/GPL/libwebsockets-2.2.2-stable-org/appveyor.yml

@@ -39,15 +39,17 @@ build_script:
   - cmake --build . --config Release
 
 # TODO: Keeps breaking Windows build, should be rewritten using CPack properly instead...
-#after_build:
+after_build:
+   - 7z a lws.zip %APPVEYOR_BUILD_FOLDER%\build\lib\Release\websockets.lib %APPVEYOR_BUILD_FOLDER%\build\lib\Release\websockets.exp %APPVEYOR_BUILD_FOLDER%\build\bin\Release\websockets.dll %APPVEYOR_BUILD_FOLDER%\lib\libwebsockets.h  %APPVEYOR_BUILD_FOLDER%\build\lws_config.h  %APPVEYOR_BUILD_FOLDER%\build\bin\Release\*.exe
 #  - cd ..
 #  - cd win32port
 #  - makensis -DVERSION=%APPVEYOR_BUILD_VERSION% libwebsockets.nsi
 
 
 artifacts:
-  - name: Installer
-    path: 'win32port/libwebsockets-*-install.exe'
+  - path: lws.zip
+    name: lws.zip
+    type: Zip
 
 cache:
   - C:\OpenSSL-Win32

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/autobahn-test.sh → EVSE/GPL/libwebsockets-2.2.2-stable-org/autobahn-test.sh


+ 69 - 0
EVSE/GPL/libwebsockets-v2.1-stable/changelog → EVSE/GPL/libwebsockets-2.2.2-stable-org/changelog

@@ -1,6 +1,75 @@
 Changelog
 ---------
 
+v2.2.0
+======
+
+Major new features
+
+ - A mount can be protected by Basic Auth... in lwsws it looks like this
+
+ ```
+{
+        "mountpoint": "/basic-auth",
+        "origin": "file://_lws_ddir_/libwebsockets-test-server/private",
+        "basic-auth": "/var/www/balogins-private"
+}
+```
+
+The text file named in `basic-auth` contains user:password information
+one per line.
+
+See README.lwsws.md for more information.
+
+ - RFC7233 RANGES support in lws server... both single and multipart.
+ This allows seeking for multimedia file serving and download resume.
+ It's enabled by default but can be disabled by CMake option.
+
+ - On Linux, lwsws can reload configuration without dropping ongoing
+ connections, when sent a SIGHUP.  The old configuration drops its
+ listen sockets so the new configuration can listen on them.
+ New connections connect to the server instance with the new
+ configuration.  When all old connections eventually close, the old
+ instance automatically exits.  This is equivalent to
+ `systemctl reload apache`
+
+ - New `adopt` api allow adoption including SSL negotiation and
+ for raw sockets and file descriptors.
+
+ - Chunked transfer encoding supported for client and server
+
+ - Adaptations to allow operations inside OPTEE Secure World
+
+ - ESP32 initial port - able to do all test server functions. See
+ README.build.md
+
+ - Serving gzipped files from inside a ZIP file is supported... this
+ includes directly serving the gzipped content if the client
+ indicated it could accept it (ie, almost all browsers) saving
+ bandwidth and time.  For clients that can't accept it, lws
+ automatically decompresses and serves the content in memory-
+ efficient chunks. Only a few hundred bytes of heap are needed
+ to serve any size file from inside the zip.  See README.coding.md
+
+ - RAW file descriptors may now be adopted into the lws event loop,
+ independent of event backend (including poll service).
+ See README.coding.md
+
+ - RAW server socket descriptors may now be enabled on the vhost if
+ the first thing sent on the connection is not a valid http method.
+ The user code can associate these with a specific protocol per
+ vhost, and RAW-specific callbacks appear there for creation, rx,
+ writable and close.  See libwebsockets-test-server-v2.0 for an example.
+ See README.coding.md
+
+ - RAW client connections are now possible using the method "RAW".
+ After connection, the socket is associated to the protocol
+ named in the client connection info and RAW-specific callbacks
+ appear there for creation, rx, writable and close.
+ See libwebsockets-test-client (with raw://) for an example.
+ See README.coding.md
+
+
 v2.1.0
 ======
 

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/cmake/FindGit.cmake → EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/FindGit.cmake


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/cmake/FindOpenSSLbins.cmake → EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/FindOpenSSLbins.cmake


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/cmake/LibwebsocketsConfig.cmake.in → EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/LibwebsocketsConfig.cmake.in


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/cmake/LibwebsocketsConfigVersion.cmake.in → EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/LibwebsocketsConfigVersion.cmake.in


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/cmake/UseRPMTools.cmake → EVSE/GPL/libwebsockets-2.2.2-stable-org/cmake/UseRPMTools.cmake


+ 36 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/component.mk

@@ -0,0 +1,36 @@
+COMPONENT_ADD_INCLUDEDIRS := ../../../../../../../../../$(COMPONENT_BUILD_DIR)/include
+
+COMPONENT_OWNBUILDTARGET:= 1
+
+CROSS_PATH1:=$(shell which xtensa-esp32-elf-gcc )
+CROSS_PATH:= $(shell dirname $(CROSS_PATH1) )/..
+
+#-DLWS_USE_BORINGSSL=1 \
+#		-DOPENSSL_ROOT_DIR="${PWD}/../../boringssl" \
+#		-DOPENSSL_LIBRARIES="${PWD}/../../boringssl/build/ssl/libssl.a;${PWD}/../../boringssl/build/crypto/libcrypto.a" \
+#		-DOPENSSL_INCLUDE_DIRS="${PWD}/../../boringssl/include" \
+
+.PHONY: build
+build:
+	cd $(COMPONENT_BUILD_DIR) ; \
+	echo "doing lws cmake" ; \
+	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 \
+		-DOPENSSL_INCLUDE_DIR=${COMPONENT_PATH}/../openssl/include \
+		-DOPENSSL_LIBRARIES=x \
+		-DLWS_WITH_ESP32=1 ;\
+	make VERBOSE=1 && \
+	cp ${COMPONENT_BUILD_DIR}/lib/libwebsockets.a ${COMPONENT_BUILD_DIR}/liblibwebsockets.a
+
+clean: myclean
+
+myclean:
+	rm -rf ./build
+
+INCLUDES := $(INCLUDES) -I build/ 
+

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/contrib/abi/README.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/contrib/abi/README.md


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/contrib/abi/libwebsockets.json → EVSE/GPL/libwebsockets-2.2.2-stable-org/contrib/abi/libwebsockets.json


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/contrib/abi/lws-abi-update.sh → EVSE/GPL/libwebsockets-2.2.2-stable-org/contrib/abi/lws-abi-update.sh


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/contrib/android-make-script.sh → EVSE/GPL/libwebsockets-2.2.2-stable-org/contrib/android-make-script.sh


+ 32 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-aarch64.cmake

@@ -0,0 +1,32 @@
+#
+# CMake Toolchain file for crosscompiling on ARM.
+#
+# This can be used when running cmake in the following way:
+#  cd build/
+#  cmake .. -DCMAKE_TOOLCHAIN_FILE=../cross-arm-linux-gnueabihf.cmake
+#
+
+# Target operating system name.
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR aarch64)
+
+# Name of C compiler.
+set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc")
+set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++")
+
+#-nostdlib
+SET(CMAKE_C_FLAGS "-DGCC_VER=\"\\\"$(GCC_VER)\\\"\" -DARM64=1 -D__LP64__=1 -Os -g3 -fpie -mstrict-align -DOPTEE_DEV_KIT=../../../optee_os/out/arm-plat-hikey/export-ta_arm64/include -fPIC -ffunction-sections -fdata-sections" CACHE STRING "" FORCE)
+
+
+# Where to look for the target environment. (More paths can be added here)
+set(CMAKE_FIND_ROOT_PATH "/projects/aist-tb/arm64-tc/")
+
+# Adjust the default behavior of the FIND_XXX() commands:
+# search programs in the host environment only.
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+
+# Search headers and libraries in the target environment only.
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/cross-arm-linux-gnueabihf.cmake → EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-arm-linux-gnueabihf.cmake


+ 3 - 14
EVSE/GPL/libwebsockets-v2.1-stable-org/cross-arm-linux-gcc.cmake → EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-esp32.cmake

@@ -6,28 +6,17 @@
 #  cmake .. -DCMAKE_TOOLCHAIN_FILE=../cross-arm-linux-gnueabihf.cmake
 #
 
-set(CROSS_PATH /opt/STLinux-2.4/devkit/armv5)
-
 # Target operating system name.
 set(CMAKE_SYSTEM_NAME Linux)
 
 # Name of C compiler.
-set(CMAKE_C_COMPILER "${CROSS_PATH}/bin/armv5-linux-gcc")
-set(CMAKE_CXX_COMPILER "${CROSS_PATH}/bin/armv5-linux-g++")
+set(CMAKE_C_COMPILER "${CROSS_PATH}/bin/xtensa-esp32-elf-gcc")
+
+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}")
 
-SET(ZLIB_INCLUDE_DIR ${CROSS_PATH}/target/usr/include)
-SET(ZLIB_LIBRARY ${CROSS_PATH}/target/usr/lib/libz.so)
-SET(OPENSSL_ROOT_DIR ../openssl-0.9.8h/release)
-SET(OPENSSL_LIBRARIES ../openssl-0.9.8h/release/lib)
-SET(OPENSSL_INCLUDE_DIR ../openssl-0.9.8h/release/openssl)
-SET(OPENSSL_CRYPTO_LIBRARY ${CROSS_PATH}/target/usr/lib/libcrypto.so)
-SET(OPENSSL_SSL_LIBRARY ${CROSS_PATH}/target/usr/lib/libssl.so)
-
-
-
 # Adjust the default behavior of the FIND_XXX() commands:
 # search programs in the host environment only.
 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/cross-ming.cmake → EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-ming.cmake


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/cross-openwrt-makefile → EVSE/GPL/libwebsockets-2.2.2-stable-org/cross-openwrt-makefile


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/doc-assets/lwsgt-overview.png → EVSE/GPL/libwebsockets-2.2.2-stable-org/doc-assets/lwsgt-overview.png


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/.gitignore → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/.gitignore


+ 83 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/alloc.c

@@ -0,0 +1,83 @@
+#include "private-libwebsockets.h"
+
+#if defined(LWS_PLAT_OPTEE)
+
+#define TEE_USER_MEM_HINT_NO_FILL_ZERO       0x80000000
+
+void *__attribute__((weak))
+	TEE_Malloc(uint32_t size, uint32_t hint)
+{
+	return NULL;
+}
+void *__attribute__((weak))
+	TEE_Realloc(void *buffer, uint32_t newSize)
+{
+	return NULL;
+}
+void __attribute__((weak))
+	TEE_Free(void *buffer)
+{
+}
+
+void *lws_realloc(void *ptr, size_t size)
+{
+	return TEE_Realloc(ptr, size);
+}
+
+void *lws_malloc(size_t size)
+{
+	return TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO);
+}
+
+void lws_free(void *p)
+{
+	TEE_Free(p);
+}
+
+void *lws_zalloc(size_t size)
+{
+	void *ptr = TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO);
+	if (ptr)
+		memset(ptr, 0, size);
+	return ptr;
+}
+
+void lws_set_allocator(void *(*cb)(void *ptr, size_t size))
+{
+	(void)cb;
+}
+#else
+
+static void *_realloc(void *ptr, size_t size)
+{
+	if (size)
+#if defined(LWS_PLAT_OPTEE)
+		return (void *)TEE_Realloc(ptr, size);
+#else
+		return (void *)realloc(ptr, size);
+#endif
+	else if (ptr)
+		free(ptr);
+	return NULL;
+}
+
+void *(*_lws_realloc)(void *ptr, size_t size) = _realloc;
+
+void *lws_realloc(void *ptr, size_t size)
+{
+	return _lws_realloc(ptr, size);
+}
+
+void *lws_zalloc(size_t size)
+{
+	void *ptr = _lws_realloc(NULL, size);
+	if (ptr)
+		memset(ptr, 0, size);
+	return ptr;
+}
+
+void lws_set_allocator(void *(*cb)(void *ptr, size_t size))
+{
+	_lws_realloc = cb;
+}
+#endif

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/base64-decode.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/base64-decode.c


+ 154 - 60
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/client-handshake.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/client-handshake.c

@@ -18,6 +18,12 @@ lws_client_connect_2(struct lws *wsi)
 
 	lwsl_client("%s\n", __func__);
 
+	if (!wsi->u.hdr.ah) {
+		cce = "ah was NULL at cc2";
+		lwsl_err("%s\n", cce);
+		goto oom4;
+	}
+
 	/* proxy? */
 
 	if (wsi->vhost->http_proxy_port) {
@@ -25,7 +31,7 @@ lws_client_connect_2(struct lws *wsi)
 			"CONNECT %s:%u HTTP/1.0\x0d\x0a"
 			"User-agent: libwebsockets\x0d\x0a",
 			lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),
-			wsi->u.hdr.c_port);
+			wsi->c_port);
 
 		if (wsi->vhost->proxy_basic_auth_token[0])
 			plen += sprintf((char *)pt->serv_buf + plen,
@@ -48,16 +54,16 @@ lws_client_connect_2(struct lws *wsi)
 #ifdef LWS_USE_IPV6
 		if (LWS_IPV6_ENABLED(wsi->vhost)) {
 			memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
-			server_addr6.sin6_port = htons(wsi->u.hdr.c_port);
+			server_addr6.sin6_port = htons(wsi->c_port);
 		} else
 #endif
-			server_addr4.sin_port = htons(wsi->u.hdr.c_port);
+			server_addr4.sin_port = htons(wsi->c_port);
 	}
 
 	/*
 	 * prepare the actual connection (to the proxy, if any)
 	 */
-       lwsl_client("%s: address %s\n", __func__, ads);
+       lwsl_notice("%s: address %s\n", __func__, ads);
 
 #ifdef LWS_USE_IPV6
 	if (LWS_IPV6_ENABLED(wsi->vhost)) {
@@ -95,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");
@@ -107,70 +115,90 @@ lws_client_connect_2(struct lws *wsi)
 	} else
 #endif
 	{
-		struct addrinfo ai, *res, *result;
+		struct addrinfo ai, *res, *result = NULL;
 		void *p = NULL;
+		int addr_rv;
 
 		memset (&ai, 0, sizeof ai);
 		ai.ai_family = PF_UNSPEC;
 		ai.ai_socktype = SOCK_STREAM;
 		ai.ai_flags = AI_CANONNAME;
 
-		if (getaddrinfo(ads, NULL, &ai, &result)) {
+		addr_rv = getaddrinfo(ads, NULL, &ai, &result);
+		if (!addr_rv) {
+			res = result;
+			while (!p && res) {
+				switch (res->ai_family) {
+				case AF_INET:
+					p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
+					break;
+				}
+
+				res = res->ai_next;
+			}
+#if defined(LWS_FALLBACK_GETHOSTBYNAME)
+		} else if (addr_rv == EAI_SYSTEM) {
+			struct hostent *host;
+
+			lwsl_info("getaddrinfo (ipv4) failed, trying gethostbyname\n");
+			host = gethostbyname(ads);
+			if (host) {
+				p = host->h_addr;
+			} else {
+				lwsl_err("gethostbyname failed\n");
+				cce = "gethostbyname (ipv4) failed";
+				goto oom4;
+			}
+#endif
+		} else {
 			lwsl_err("getaddrinfo failed\n");
 			cce = "getaddrinfo (ipv4) failed";
 			goto oom4;
 		}
 
-		res = result;
-		while (!p && res) {
-			switch (res->ai_family) {
-			case AF_INET:
-				p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
-				break;
-			}
-
-			res = res->ai_next;
-		}
-
 		if (!p) {
+			if (result)
+				freeaddrinfo(result);
 			lwsl_err("Couldn't identify address\n");
-			freeaddrinfo(result);
+			cce = "unable to lookup address";
 			goto oom4;
 		}
 
 		server_addr4.sin_family = AF_INET;
 		server_addr4.sin_addr = *((struct in_addr *)p);
 		bzero(&server_addr4.sin_zero, 8);
-		freeaddrinfo(result);
+		if (result)
+			freeaddrinfo(result);
 	}
 
-	if (!lws_socket_is_valid(wsi->sock)) {
+	if (!lws_socket_is_valid(wsi->desc.sockfd)) {
 
 #ifdef LWS_USE_IPV6
 		if (LWS_IPV6_ENABLED(wsi->vhost))
-			wsi->sock = socket(AF_INET6, SOCK_STREAM, 0);
+			wsi->desc.sockfd = socket(AF_INET6, SOCK_STREAM, 0);
 		else
 #endif
-			wsi->sock = socket(AF_INET, SOCK_STREAM, 0);
+			wsi->desc.sockfd = socket(AF_INET, SOCK_STREAM, 0);
 
-		if (!lws_socket_is_valid(wsi->sock)) {
+		if (!lws_socket_is_valid(wsi->desc.sockfd)) {
 			lwsl_warn("Unable to open socket\n");
+			cce = "unable to open socket";
 			goto oom4;
 		}
 
-		if (lws_plat_set_socket_options(wsi->vhost, wsi->sock)) {
+		if (lws_plat_set_socket_options(wsi->vhost, wsi->desc.sockfd)) {
 			lwsl_err("Failed to set wsi socket options\n");
-			compatible_close(wsi->sock);
+			compatible_close(wsi->desc.sockfd);
 			cce = "set socket opts failed";
 			goto oom4;
 		}
 
 		wsi->mode = LWSCM_WSCL_WAITING_CONNECT;
 
-		lws_libev_accept(wsi, wsi->sock);
-		lws_libuv_accept(wsi, wsi->sock);
+		lws_libev_accept(wsi, wsi->desc);
+		lws_libuv_accept(wsi, wsi->desc);
 		if (insert_wsi_socket_into_fds(context, wsi)) {
-			compatible_close(wsi->sock);
+			compatible_close(wsi->desc.sockfd);
 			cce = "insert wsi failed";
 			goto oom4;
 		}
@@ -191,9 +219,11 @@ lws_client_connect_2(struct lws *wsi)
 		lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,
 				AWAITING_TIMEOUT);
 
-		n = lws_socket_bind(wsi->vhost, wsi->sock, 0, wsi->vhost->iface);
-		if (n < 0)
+		n = lws_socket_bind(wsi->vhost, wsi->desc.sockfd, 0, wsi->vhost->iface);
+		if (n < 0) {
+			cce = "unable to bind socket";
 			goto failed;
+		}
 	}
 
 #ifdef LWS_USE_IPV6
@@ -207,7 +237,7 @@ lws_client_connect_2(struct lws *wsi)
 		n = sizeof(struct sockaddr);
 	}
 
-	if (connect(wsi->sock, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) {
+	if (connect(wsi->desc.sockfd, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) {
 		if (LWS_ERRNO == LWS_EALREADY ||
 		    LWS_ERRNO == LWS_EINPROGRESS ||
 		    LWS_ERRNO == LWS_EWOULDBLOCK
@@ -218,21 +248,26 @@ lws_client_connect_2(struct lws *wsi)
 			lwsl_client("nonblocking connect retry (errno = %d)\n",
 				    LWS_ERRNO);
 
-			if (lws_plat_check_connection_error(wsi))
+			if (lws_plat_check_connection_error(wsi)) {
+				cce = "socket connect failed";
 				goto failed;
+			}
 
 			/*
 			 * must do specifically a POLLOUT poll to hear
 			 * about the connect completion
 			 */
-			if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
+			if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
+				cce = "POLLOUT set failed";
 				goto failed;
+			}
 
 			return wsi;
 		}
 
 		if (LWS_ERRNO != LWS_EISCONN) {
-			lwsl_debug("Connect failed errno=%d\n", LWS_ERRNO);
+			lwsl_notice("Connect failed errno=%d\n", LWS_ERRNO);
+			cce = "connect failed";
 			goto failed;
 		}
 	}
@@ -252,12 +287,13 @@ lws_client_connect_2(struct lws *wsi)
 		if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
 					  wsi->vhost->http_proxy_address))
 			goto failed;
-		wsi->u.hdr.c_port = wsi->vhost->http_proxy_port;
+		wsi->c_port = wsi->vhost->http_proxy_port;
 
-		n = send(wsi->sock, (char *)pt->serv_buf, plen,
+		n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen,
 			 MSG_NOSIGNAL);
 		if (n < 0) {
 			lwsl_debug("ERROR writing to proxy socket\n");
+			cce = "proxy write failed";
 			goto failed;
 		}
 
@@ -283,13 +319,15 @@ lws_client_connect_2(struct lws *wsi)
 			AWAITING_TIMEOUT);
 
 	wsi->mode = LWSCM_WSCL_ISSUE_HANDSHAKE;
-	pfd.fd = wsi->sock;
+	pfd.fd = wsi->desc.sockfd;
 	pfd.events = LWS_POLLIN;
 	pfd.revents = LWS_POLLIN;
 
 	n = lws_service_fd(context, &pfd);
-	if (n < 0)
+	if (n < 0) {
+		cce = "first service failed";
 		goto failed;
+	}
 	if (n) /* returns 1 on failure after closing wsi */
 		return NULL;
 
@@ -297,9 +335,11 @@ lws_client_connect_2(struct lws *wsi)
 
 oom4:
 	/* we're closing, losing some rx is OK */
-	wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
-	//lwsl_err("%d\n", wsi->mode);
-	if (wsi->mode == LWSCM_HTTP_CLIENT) {
+	if (wsi->u.hdr.ah)
+		wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
+	if (wsi->mode == LWSCM_HTTP_CLIENT ||
+	    wsi->mode == LWSCM_HTTP_CLIENT_ACCEPTED ||
+	    wsi->mode == LWSCM_WSCL_WAITING_CONNECT) {
 		wsi->vhost->protocols[0].callback(wsi,
 			LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
 			wsi->user_space, (void *)cce, strlen(cce));
@@ -307,13 +347,19 @@ oom4:
 	}
 	/* take care that we might be inserted in fds already */
 	if (wsi->position_in_fds_table != -1)
-		goto failed;
+		goto failed1;
+	lws_remove_from_timeout_list(wsi);
 	lws_header_table_detach(wsi, 0);
 	lws_free(wsi);
 
 	return NULL;
 
 failed:
+	wsi->vhost->protocols[0].callback(wsi,
+		LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
+		wsi->user_space, (void *)cce, strlen(cce));
+	wsi->already_did_cce = 1;
+failed1:
 	lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
 
 	return NULL;
@@ -329,13 +375,17 @@ failed:
  * host:	host header to send to the new server
  */
 LWS_VISIBLE struct lws *
-lws_client_reset(struct lws *wsi, int ssl, const char *address, int port, const char *path, const char *host)
+lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
+		 const char *path, const char *host)
 {
-	if (wsi->u.hdr.redirects == 3) {
+	char origin[300] = "", protocol[300] = "", method[32] = "", *p;
+	struct lws *wsi = *pwsi;
+
+	if (wsi->redirects == 3) {
 		lwsl_err("%s: Too many redirects\n", __func__);
 		return NULL;
 	}
-	wsi->u.hdr.redirects++;
+	wsi->redirects++;
 
 #ifdef LWS_OPENSSL_SUPPORT
 	wsi->use_ssl = ssl;
@@ -346,26 +396,61 @@ lws_client_reset(struct lws *wsi, int ssl, const char *address, int port, const
 	}
 #endif
 
-	lwsl_notice("redirect ads='%s', port=%d, path='%s'\n", address, port, path);
+	p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN);
+	if (p)
+		strncpy(origin, p, sizeof(origin) - 1);
 
-	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
-		return NULL;
+	p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
+	if (p)
+		strncpy(protocol, p, sizeof(protocol) - 1);
 
-	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, path))
-		return NULL;
+	p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD);
+	if (p)
+		strncpy(method, p, sizeof(method) - 1);
 
-	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
-		return NULL;
+	lwsl_debug("redirect ads='%s', port=%d, path='%s', ssl = %d\n",
+		   address, port, path, ssl);
+
+	/* close the connection by hand */
 
-	compatible_close(wsi->sock);
+	compatible_close(wsi->desc.sockfd);
 	remove_wsi_socket_from_fds(wsi);
-	wsi->sock = LWS_SOCK_INVALID;
+
+	wsi->desc.sockfd = LWS_SOCK_INVALID;
 	wsi->state = LWSS_CLIENT_UNCONNECTED;
 	wsi->protocol = NULL;
 	wsi->pending_timeout = NO_PENDING_TIMEOUT;
-	wsi->u.hdr.c_port = port;
+	wsi->c_port = port;
+	wsi->hdr_parsing_completed = 0;
+	_lws_header_table_reset(wsi->u.hdr.ah);
 
-	return lws_client_connect_2(wsi);
+	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
+		return NULL;
+
+	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
+		return NULL;
+
+	if (origin[0])
+		if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN,
+					  origin))
+			return NULL;
+	if (protocol[0])
+		if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
+					  protocol))
+			return NULL;
+	if (method[0])
+		if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD,
+					  method))
+			return NULL;
+
+	origin[0] = '/';
+	strncpy(&origin[1], path, sizeof(origin) - 2);
+	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, origin))
+		return NULL;
+
+	*pwsi = lws_client_connect_2(wsi);
+
+	return *pwsi;
 }
 
 #ifdef LWS_WITH_HTTP_PROXY
@@ -483,6 +568,7 @@ lws_client_connect_via_info(struct lws_client_connect_info *i)
 {
 	struct lws *wsi;
 	int v = SPEC_LATEST_SUPPORTED;
+	const struct lws_protocols *p;
 
 	if (i->context->requested_kill)
 		return NULL;
@@ -497,7 +583,7 @@ lws_client_connect_via_info(struct lws_client_connect_info *i)
 	wsi->context = i->context;
 	/* assert the mode and union status (hdr) clearly */
 	lws_union_transition(wsi, LWSCM_HTTP_CLIENT);
-	wsi->sock = LWS_SOCK_INVALID;
+	wsi->desc.sockfd = LWS_SOCK_INVALID;
 
 	/* 1) fill up the wsi with stuff from the connect_info as far as it
 	 * can go.  It's because not only is our connection async, we might
@@ -511,15 +597,23 @@ lws_client_connect_via_info(struct lws_client_connect_info *i)
 	wsi->ietf_spec_revision = v;
 	wsi->user_space = NULL;
 	wsi->state = LWSS_CLIENT_UNCONNECTED;
-	wsi->protocol = NULL;
 	wsi->pending_timeout = NO_PENDING_TIMEOUT;
 	wsi->position_in_fds_table = -1;
-	wsi->u.hdr.c_port = i->port;
+	wsi->c_port = i->port;
 	wsi->vhost = i->vhost;
 	if (!wsi->vhost)
 		wsi->vhost = i->context->vhost_list;
 
 	wsi->protocol = &wsi->vhost->protocols[0];
+
+	/* for http[s] connection, allow protocol selection by name */
+
+	if (i->method && i->vhost && i->protocol) {
+		p = lws_vhost_name_to_protocol(i->vhost, i->protocol);
+		if (p)
+			wsi->protocol = p;
+	}
+
 	if (wsi && !wsi->user_space && i->userdata) {
 		wsi->user_space_externally_allocated = 1;
 		wsi->user_space = i->userdata;
@@ -673,7 +767,7 @@ lws_client_connect_via_info2(struct lws *wsi)
 	if (lws_ext_cb_all_exts(wsi->context, wsi,
 				LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION,
 				(void *)stash->address,
-				wsi->u.hdr.c_port) > 0) {
+				wsi->c_port) > 0) {
 		lwsl_client("lws_client_connect: ext handling conn\n");
 
 		lws_set_timeout(wsi,

+ 50 - 32
EVSE/GPL/libwebsockets-v2.1-stable/lib/client-parser.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/client-parser.c

@@ -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__, c);
 		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,13 +385,23 @@ spill:
 					wsi->user_space, pp,
 					wsi->u.ws.rx_ubuf_head))
 				return -1;
-			/*
-			 * parrot the close packet payload back
-			 * we do not care about how it went, we are closing
-			 * immediately afterwards
-			 */
-			lws_write(wsi, (unsigned char *)&wsi->u.ws.rx_ubuf[LWS_PRE],
-				  wsi->u.ws.rx_ubuf_head, LWS_WRITE_CLOSE);
+
+			if (lws_partial_buffered(wsi))
+				/*
+				 * if we're in the middle of something,
+				 * we can't do a normal close response and
+				 * have to just close our end.
+				 */
+				wsi->socket_is_permanently_unusable = 1;
+			else
+				/*
+				 * parrot the close packet payload back
+				 * we do not care about how it went, we are closing
+				 * immediately afterwards
+				 */
+				lws_write(wsi, (unsigned char *)&wsi->u.ws.rx_ubuf[LWS_PRE],
+					  wsi->u.ws.rx_ubuf_head,
+					  LWS_WRITE_CLOSE);
 			wsi->state = LWSS_RETURNED_CLOSE_ALREADY;
 			/* close the connection */
 			return -1;
@@ -487,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);
 
@@ -506,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;
@@ -528,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;

+ 134 - 24
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/client.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/client.c

@@ -37,7 +37,7 @@ lws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len)
 			 * we were accepting input but now we stopped doing so
 			 */
 			if (!(wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) {
-				lwsl_debug("%s: caching %d\n", __func__, len);
+				lwsl_debug("%s: caching %ld\n", __func__, (long)len);
 				lws_rxflow_cache(wsi, *buf, 0, len);
 				return 0;
 			}
@@ -57,7 +57,7 @@ lws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len)
 			}
 			len--;
 		}
-		lwsl_debug("%s: finished with %d\n", __func__, len);
+		lwsl_debug("%s: finished with %ld\n", __func__, (long)len);
 		return 0;
 	default:
 		break;
@@ -114,7 +114,7 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi,
 			return 0;
 		}
 
-		n = recv(wsi->sock, sb, context->pt_serv_buf_size, 0);
+		n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0);
 		if (n < 0) {
 			if (LWS_ERRNO == LWS_EAGAIN) {
 				lwsl_debug("Proxy read returned EAGAIN... retrying\n");
@@ -196,6 +196,9 @@ lws_client_socket_service(struct lws_context *context, struct lws *wsi,
 	case LWSCM_WSCL_ISSUE_HANDSHAKE2:
 		p = lws_generate_client_handshake(wsi, p);
 		if (p == NULL) {
+			if (wsi->mode == LWSCM_RAW)
+				return 0;
+
 			lwsl_err("Failed to generate handshake for client\n");
 			lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
 			return 0;
@@ -346,7 +349,12 @@ static void
 strtolower(char *s)
 {
 	while (*s) {
+#ifdef LWS_PLAT_OPTEE
+		int tolower_optee(int c);
+		*s = tolower_optee((int)*s);
+#else
 		*s = tolower((int)*s);
+#endif
 		s++;
 	}
 }
@@ -387,6 +395,15 @@ lws_http_transaction_completed_client(struct lws *wsi)
 	return 0;
 }
 
+LWS_VISIBLE LWS_EXTERN unsigned int
+lws_http_client_http_response(struct lws *wsi)
+{
+	if (!wsi->u.http.ah)
+		return 0;
+
+	return wsi->u.http.ah->http_response;
+}
+
 int
 lws_client_interpret_server_handshake(struct lws *wsi)
 {
@@ -394,8 +411,9 @@ lws_client_interpret_server_handshake(struct lws *wsi)
 	int close_reason = LWS_CLOSE_STATUS_PROTOCOL_ERR;
 	struct lws_context *context = wsi->context;
 	const char *pc, *prot, *ads = NULL, *path, *cce = NULL;
-	struct allocated_headers *ah;
-	char *p;
+	struct allocated_headers *ah = NULL;
+	char *p, *q;
+	char new_path[300];
 #ifndef LWS_NO_EXTENSIONS
 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
 	char *sb = (char *)&pt->serv_buf[0];
@@ -408,13 +426,14 @@ 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;
+		ah->http_response = 0;
 	}
 
 	/*
@@ -450,6 +469,9 @@ lws_client_interpret_server_handshake(struct lws *wsi)
 		goto bail3;
 	}
 	n = atoi(p);
+	if (ah)
+		ah->http_response = n;
+
 	if (n == 301 || n == 302 || n == 303 || n == 307 || n == 308) {
 		p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_LOCATION);
 		if (!p) {
@@ -457,26 +479,79 @@ lws_client_interpret_server_handshake(struct lws *wsi)
 			goto bail3;
 		}
 
-		if (lws_parse_uri(p, &prot, &ads, &port, &path)) {
-			cce = "HS: URI did not parse";
-			goto bail3;
+		/* Relative reference absolute path */
+		if (p[0] == '/')
+		{
+#ifdef LWS_OPENSSL_SUPPORT
+			ssl = wsi->use_ssl;
+#endif
+			ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
+			port = wsi->c_port;
+			path = p + 1; /* +1 as lws_client_reset expects leading / to be omitted */
 		}
+		/* Absolute (Full) URI */
+		else if (strchr(p, ':'))
+		{
+			if (lws_parse_uri(p, &prot, &ads, &port, &path)) {
+				cce = "HS: URI did not parse";
+				goto bail3;
+			}
 
-		if (!strcmp(prot, "wss://") || !strcmp(prot, "https://"))
-			ssl = 1;
+			if (!strcmp(prot, "wss") || !strcmp(prot, "https"))
+				ssl = 1;
+		}
+		/* Relative reference relative path */
+		else
+		{
+			/* This doesn't try to calculate an absolute path, that will be left to the server */
+#ifdef LWS_OPENSSL_SUPPORT
+			ssl = wsi->use_ssl;
+#endif
+			ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
+			port = wsi->c_port;
+			path = new_path + 1; /* +1 as lws_client_reset expects leading / to be omitted */
+			strncpy(new_path, lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI), sizeof(new_path));
+			new_path[sizeof(new_path) - 1] = '\0';
+			q = strrchr(new_path, '/');
+			if (q)
+			{
+				strncpy(q + 1, p, sizeof(new_path) - (q - new_path) - 1);
+				new_path[sizeof(new_path) - 1] = '\0';
+			}
+			else
+			{
+				path = p;
+			}
+		}
 
-		if (lws_client_reset(wsi, ssl, ads, port, path, ads)) {
+#ifdef LWS_OPENSSL_SUPPORT
+		if (wsi->use_ssl && !ssl) {
+			cce = "HS: Redirect attempted SSL downgrade";
+			goto bail3;
+		}
+#endif
+
+		if (!lws_client_reset(&wsi, ssl, ads, port, path, ads)) {
+			/* there are two ways to fail out with NULL return...
+			 * simple, early problem where the wsi is intact, or
+			 * we went through with the reconnect attempt and the
+			 * wsi is already closed.  In the latter case, the wsi
+			 * has beet set to NULL additionally.
+			 */
 			lwsl_err("Redirect failed\n");
 			cce = "HS: Redirect failed";
-			goto bail3;
+			if (wsi)
+				goto bail3;
+
+			return 1;
 		}
 		return 0;
 	}
 
 	if (!wsi->do_ws) {
-		if (n != 200) {
-			lwsl_notice("Connection failed with code %d", n);
-			cce = "HS: Server did not return 200";
+		if (n != 200 && n != 304) {
+			lwsl_notice("Connection failed with code %d\n", n);
+			cce = "HS: Server did not return 200 or 304";
 			goto bail2;
 		}
 
@@ -608,6 +683,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
 		 * no protocol name to work from,
 		 * default to first protocol
 		 */
+		n = 0;
 		wsi->protocol = &wsi->vhost->protocols[0];
 		goto check_extensions;
 	}
@@ -652,7 +728,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
 		goto bail2;
 	}
 
-
+check_extensions:
 	/*
 	 * stitch protocol choice into the vh protocol linked list
 	 * We always insert ourselves at the start of the list
@@ -676,7 +752,6 @@ lws_client_interpret_server_handshake(struct lws *wsi)
 		wsi->same_vh_protocol_next->same_vh_protocol_prev =
 				&wsi->same_vh_protocol_next;
 
-check_extensions:
 #ifndef LWS_NO_EXTENSIONS
 	/* instantiate the accepted extensions */
 
@@ -798,7 +873,7 @@ check_extensions:
 				      wsi->act_ext_user[wsi->count_act_ext],
 				      NULL, 0)) {
 				lwsl_err("%s: ext %s rejects server options %s",
-					 ext->name, a);
+					 __func__, ext->name, a);
 				cce = "HS: EXT: Rejects server options";
 				goto bail2;
 			}
@@ -880,7 +955,7 @@ check_accept:
        wsi->u.ws.rx_ubuf_alloc = n;
 	lwsl_info("Allocating client RX buffer %d\n", n);
 
-	if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n,
+	if (setsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&n,
 		       sizeof n)) {
 		lwsl_warn("Failed to set SNDBUF to %d", n);
 		cce = "HS: SO_SNDBUF failed";
@@ -955,6 +1030,36 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt)
 	} else
 		wsi->do_ws = 0;
 
+	if (!strcmp(meth, "RAW")) {
+		const char *pp = lws_hdr_simple_ptr(wsi,
+					_WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
+		lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
+		lwsl_notice("client transition to raw\n");
+		if (pp) {
+			const struct lws_protocols *pr;
+
+			pr = lws_vhost_name_to_protocol(wsi->vhost, pp);
+
+			if (!pr) {
+				lwsl_err("protocol %s not enabled on vhost\n",
+					 pp);
+				return NULL;
+			}
+
+			lws_bind_protocol(wsi, pr);
+		}
+		if ((wsi->protocol->callback)(wsi,
+				LWS_CALLBACK_RAW_ADOPT,
+				wsi->user_space, NULL, 0))
+			return NULL;
+
+		wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
+		lws_union_transition(wsi, LWSCM_RAW);
+		lws_header_table_detach(wsi, 1);
+
+		return NULL;
+	}
+
 	if (wsi->do_ws) {
 		/*
 		 * create the random key
@@ -992,9 +1097,14 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt)
 	p += sprintf(p, "Host: %s\x0d\x0a",
 		     lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST));
 
-	if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN))
-		p += sprintf(p, "Origin: http://%s\x0d\x0a",
-			     lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN));
+	if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN)) {
+		if (lws_check_opt(context->options, LWS_SERVER_OPTION_JUST_USE_RAW_ORIGIN))
+			p += sprintf(p, "Origin: %s\x0d\x0a",
+				     lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN));
+		else
+			p += sprintf(p, "Origin: http://%s\x0d\x0a",
+				     lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN));
+	}
 
 	if (wsi->do_ws) {
 		p += sprintf(p, "Upgrade: websocket\x0d\x0a"
@@ -1069,7 +1179,7 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt)
 
 	/* give userland a chance to append, eg, cookies */
 
-	wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
+	wsi->protocol->callback(wsi, LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
 				wsi->user_space, &p, (pkt + context->pt_serv_buf_size) - p - 12);
 
 	p += sprintf(p, "\x0d\x0a");

+ 219 - 55
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/context.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/context.c

@@ -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,
@@ -122,7 +124,11 @@ lws_vhost_protocol_options(struct lws_vhost *vh, const char *name)
 	return NULL;
 }
 
-int
+/*
+ * inform every vhost that hasn't already done it, that
+ * his protocols are initializing
+ */
+LWS_VISIBLE int
 lws_protocol_init(struct lws_context *context)
 {
 	struct lws_vhost *vh = context->vhost_list;
@@ -133,16 +139,21 @@ lws_protocol_init(struct lws_context *context)
 	memset(&wsi, 0, sizeof(wsi));
 	wsi.context = context;
 
-	lwsl_notice("%s\n", __func__);
+	lwsl_info("%s\n", __func__);
 
 	while (vh) {
 		wsi.vhost = vh;
 
+		/* only do the protocol init once for a given vhost */
+		if (vh->created_vhost_protocols)
+			goto next;
+
 		/* initialize supported protocols on this vhost */
 
 		for (n = 0; n < vh->count_protocols; n++) {
 			wsi.protocol = &vh->protocols[n];
-
+			if (!vh->protocols[n].name)
+				continue;
 			pvo = lws_vhost_protocol_options(vh,
 							 vh->protocols[n].name);
 			if (pvo) {
@@ -166,6 +177,13 @@ lws_protocol_init(struct lws_context *context)
 						   vh->protocols[n].name);
 						vh->default_protocol_index = n;
 					}
+					if (!strcmp(pvo->name, "raw")) {
+						lwsl_notice("Setting raw "
+						   "protocol for vh %s to %s\n",
+						   vh->name,
+						   vh->protocols[n].name);
+						vh->raw_protocol_index = n;
+					}
 					pvo = pvo->next;
 				}
 
@@ -185,11 +203,15 @@ lws_protocol_init(struct lws_context *context)
 				return 1;
 		}
 
+		vh->created_vhost_protocols = 1;
+next:
 		vh = vh->vhost_next;
 	}
 
+	if (!context->protocol_init_done)
+		lws_finalize_startup(context);
+
 	context->protocol_init_done = 1;
-	lws_finalize_startup(context);
 
 	return 0;
 }
@@ -289,13 +311,18 @@ static const struct lws_protocols protocols_dummy[] = {
 		lws_callback_http_dummy,		/* callback */
 		0,	/* per_session_data_size */
 		0,			/* max frame size / rx buffer */
+		0, NULL
 	},
 	/*
 	 * the other protocols are provided by lws plugins
 	 */
-	{ NULL, NULL, 0, 0 } /* terminator */
+	{ NULL, NULL, 0, 0, 0, NULL} /* terminator */
 };
 
+#ifdef LWS_PLAT_OPTEE
+#undef LWS_HAVE_GETENV
+#endif
+
 LWS_VISIBLE struct lws_vhost *
 lws_create_vhost(struct lws_context *context,
 		 struct lws_context_creation_info *info)
@@ -306,9 +333,9 @@ lws_create_vhost(struct lws_context *context,
 	const struct lws_protocol_vhost_options *pvo;
 #ifdef LWS_WITH_PLUGINS
 	struct lws_plugin *plugin = context->plugin_list;
+#endif
 	struct lws_protocols *lwsp;
 	int m, f = !info->pvo;
-#endif
 #ifdef LWS_HAVE_GETENV
 	char *p;
 #endif
@@ -340,29 +367,31 @@ lws_create_vhost(struct lws_context *context,
 	else
 		vh->keepalive_timeout = 5;
 
-#ifdef LWS_WITH_PLUGINS
-	if (plugin) {
-		/*
-		 * give the vhost a unified list of protocols including the
-		 * ones that came from plugins
-		 */
-		lwsp = lws_zalloc(sizeof(struct lws_protocols) *
-					   (vh->count_protocols +
-					   context->plugin_protocol_count + 1));
-		if (!lwsp)
-			return NULL;
+	/*
+	 * give the vhost a unified list of protocols including the
+	 * ones that came from plugins
+	 */
+	lwsp = lws_zalloc(sizeof(struct lws_protocols) *
+				   (vh->count_protocols +
+				   context->plugin_protocol_count + 1));
+	if (!lwsp) {
+		lwsl_err("OOM\n");
+		return NULL;
+	}
 
-		m = vh->count_protocols;
-		memcpy(lwsp, info->protocols,
-		       sizeof(struct lws_protocols) * m);
+	m = vh->count_protocols;
+	memcpy(lwsp, info->protocols, sizeof(struct lws_protocols) * m);
 
-		/* for compatibility, all protocols enabled on vhost if only
-		 * the default vhost exists.  Otherwise only vhosts who ask
-		 * for a protocol get it enabled.
-		 */
+	/* for compatibility, all protocols enabled on vhost if only
+	 * the default vhost exists.  Otherwise only vhosts who ask
+	 * for a protocol get it enabled.
+	 */
 
-		if (info->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
-			f = 0;
+	if (info->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
+		f = 0;
+	(void)f;
+#ifdef LWS_WITH_PLUGINS
+	if (plugin) {
 
 		while (plugin) {
 			for (n = 0; n < plugin->caps.count_protocols; n++) {
@@ -381,10 +410,19 @@ lws_create_vhost(struct lws_context *context,
 			}
 			plugin = plugin->list;
 		}
-		vh->protocols = lwsp;
-	} else
+	}
 #endif
+
+	if (
+#ifdef LWS_WITH_PLUGINS
+	    (context->plugin_list) ||
+#endif
+	    info->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
+		vh->protocols = lwsp;
+	else {
 		vh->protocols = info->protocols;
+		free(lwsp);
+	}
 
 	vh->same_vh_protocol_list = (struct lws **)
 			lws_zalloc(sizeof(struct lws *) * vh->count_protocols);
@@ -502,15 +540,14 @@ lws_create_vhost(struct lws_context *context,
 	} else
 		vh->log_fd = (int)LWS_INVALID_FILE;
 #endif
-
 	if (lws_context_init_server_ssl(info, vh))
 		goto bail;
-
 	if (lws_context_init_client_ssl(info, vh))
 		goto bail;
-
-	if (lws_context_init_server(info, vh))
+	if (lws_context_init_server(info, vh)) {
+		lwsl_err("init server failed\n");
 		goto bail;
+	}
 
 	while (1) {
 		if (!(*vh1)) {
@@ -519,6 +556,10 @@ lws_create_vhost(struct lws_context *context,
 		}
 		vh1 = &(*vh1)->vhost_next;
 	};
+	/* for the case we are adding a vhost much later, after server init */
+
+	if (context->protocol_init_done)
+		lws_protocol_init(context);
 
 	return vh;
 
@@ -539,12 +580,12 @@ lws_init_vhost_client_ssl(const struct lws_context_creation_info *info,
 
 	return lws_context_init_client_ssl(&i, vhost);
 }
-	struct lws wsi;
 
 LWS_VISIBLE struct lws_context *
 lws_create_context(struct lws_context_creation_info *info)
 {
 	struct lws_context *context = NULL;
+	struct lws_plat_file_ops *prev;
 #ifndef LWS_NO_DAEMONIZE
 	int pid_daemon = get_daemonize_pid();
 #endif
@@ -555,6 +596,9 @@ lws_create_context(struct lws_context_creation_info *info)
 
 	lwsl_notice("Initial logging level %d\n", log_level);
 	lwsl_notice("Libwebsockets version: %s\n", library_version);
+#if defined(GCC_VER)
+	lwsl_notice("Compiled with  %s\n", GCC_VER);
+#endif
 #if LWS_POSIX
 #ifdef LWS_USE_IPV6
 	if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_IPV6))
@@ -564,14 +608,16 @@ lws_create_context(struct lws_context_creation_info *info)
 #else
 	lwsl_notice("IPV6 not compiled in\n");
 #endif
+#if !defined(LWS_PLAT_OPTEE) && !defined(LWS_PLAT_ESP32)
 	lws_feature_status_libev(info);
 	lws_feature_status_libuv(info);
+#endif
 #endif
 	lwsl_info(" LWS_DEF_HEADER_LEN    : %u\n", LWS_DEF_HEADER_LEN);
 	lwsl_info(" LWS_MAX_PROTOCOLS     : %u\n", LWS_MAX_PROTOCOLS);
 	lwsl_info(" LWS_MAX_SMP           : %u\n", LWS_MAX_SMP);
 	lwsl_info(" SPEC_LATEST_SUPPORTED : %u\n", SPEC_LATEST_SUPPORTED);
-	lwsl_info(" sizeof (*info)        : %u\n", sizeof(*info));
+	lwsl_info(" sizeof (*info)        : %ld\n", (long)sizeof(*info));
 #if LWS_POSIX
 	lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH);
 #endif
@@ -588,7 +634,44 @@ lws_create_context(struct lws_context_creation_info *info)
 	else
 		context->pt_serv_buf_size = 4096;
 
+	/* default to just the platform fops implementation */
+
+	context->fops_platform.LWS_FOP_OPEN	= _lws_plat_file_open;
+	context->fops_platform.LWS_FOP_CLOSE	= _lws_plat_file_close;
+	context->fops_platform.LWS_FOP_SEEK_CUR	= _lws_plat_file_seek_cur;
+	context->fops_platform.LWS_FOP_READ	= _lws_plat_file_read;
+	context->fops_platform.LWS_FOP_WRITE	= _lws_plat_file_write;
+	context->fops_platform.fi[0].sig	= NULL;
+
+	/*
+	 *  arrange a linear linked-list of fops starting from context->fops
+	 *
+	 * platform fops
+	 * [ -> fops_zip (copied into context so .next settable) ]
+	 * [ -> info->fops ]
+	 */
+
+	context->fops = &context->fops_platform;
+	prev = (struct lws_plat_file_ops *)context->fops;
+
+#if defined(LWS_WITH_ZIP_FOPS)
+	/* make a soft copy so we can set .next */
+	context->fops_zip = fops_zip;
+	prev->next = &context->fops_zip;
+	prev = (struct lws_plat_file_ops *)prev->next;
+#endif
+
+	/* if user provided fops, tack them on the end of the list */
+	if (info->fops)
+		prev->next = info->fops;
+
+	context->reject_service_keywords = info->reject_service_keywords;
+	if (info->external_baggage_free_on_destroy)
+		context->external_baggage_free_on_destroy =
+			info->external_baggage_free_on_destroy;
+
 	context->time_up = time(NULL);
+
 #ifndef LWS_NO_DAEMONIZE
 	if (pid_daemon) {
 		context->started_with_parent = pid_daemon;
@@ -681,9 +764,6 @@ lws_create_context(struct lws_context_creation_info *info)
 	lwsl_notice(" Threads: %d each %d fds\n", context->count_threads,
 		    context->fd_limit_per_thread);
 
-	memset(&wsi, 0, sizeof(wsi));
-	wsi.context = context;
-
 	if (!info->ka_interval && info->ka_time > 0) {
 		lwsl_err("info->ka_interval can't be 0 if ka_time used\n");
 		return NULL;
@@ -710,20 +790,20 @@ lws_create_context(struct lws_context_creation_info *info)
 	context->lws_uv_sigint_cb = &lws_uv_sigint_cb;
 #endif
 
-	lwsl_info(" mem: context:         %5u bytes (%d ctx + (%d thr x %d))\n",
-		  sizeof(struct lws_context) +
+	lwsl_info(" mem: context:         %5lu bytes (%ld ctx + (%ld thr x %d))\n",
+		  (long)sizeof(struct lws_context) +
 		  (context->count_threads * context->pt_serv_buf_size),
-		  sizeof(struct lws_context),
-		  context->count_threads,
+		  (long)sizeof(struct lws_context),
+		  (long)context->count_threads,
 		  context->pt_serv_buf_size);
 
-	lwsl_info(" mem: http hdr rsvd:   %5u bytes (%u thr x (%u + %u) x %u))\n",
-		    (context->max_http_header_data +
+	lwsl_info(" mem: http hdr rsvd:   %5lu bytes (%u thr x (%u + %lu) x %u))\n",
+		    (long)(context->max_http_header_data +
 		     sizeof(struct allocated_headers)) *
 		    context->max_http_header_pool * context->count_threads,
 		    context->count_threads,
 		    context->max_http_header_data,
-		    sizeof(struct allocated_headers),
+		    (long)sizeof(struct allocated_headers),
 		    context->max_http_header_pool);
 	n = sizeof(struct lws_pollfd) * context->count_threads *
 	    context->fd_limit_per_thread;
@@ -738,9 +818,6 @@ lws_create_context(struct lws_context_creation_info *info)
 		context->server_string = info->server_string;
 		context->server_string_len = (short)
 				strlen(context->server_string);
-	} else {
-		context->server_string = "libwebsockets";
-		context->server_string_len = 13;
 	}
 
 #if LWS_MAX_SMP > 1
@@ -769,8 +846,8 @@ lws_create_context(struct lws_context_creation_info *info)
 
 	lws_context_init_extensions(info, context);
 
-	lwsl_notice(" mem: per-conn:        %5u bytes + protocol rx buf\n",
-		    sizeof(struct lws));
+	lwsl_notice(" mem: per-conn:        %5lu bytes + protocol rx buf\n",
+		    (unsigned long)sizeof(struct lws));
 
 	strcpy(context->canonical_hostname, "unknown");
 	lws_server_get_canonical_hostname(context, info);
@@ -806,22 +883,79 @@ bail:
 	return NULL;
 }
 
+LWS_VISIBLE LWS_EXTERN void
+lws_context_deprecate(struct lws_context *context, lws_reload_func cb)
+{
+	struct lws_vhost *vh = context->vhost_list, *vh1;
+	struct lws *wsi;
+
+	/*
+	 * "deprecation" means disable the context from accepting any new
+	 * connections and free up listen sockets to be used by a replacement
+	 * context.
+	 *
+	 * Otherwise the deprecated context remains operational, until its
+	 * number of connected sockets falls to zero, when it is deleted.
+	 */
+
+	/* for each vhost, close his listen socket */
+
+	while (vh) {
+		wsi = vh->lserv_wsi;
+		if (wsi) {
+			wsi->socket_is_permanently_unusable = 1;
+			lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
+			wsi->context->deprecation_pending_listen_close_count++;
+			/*
+			 * other vhosts can share the listen port, they
+			 * point to the same wsi.  So zap those too.
+			 */
+			vh1 = context->vhost_list;
+			while (vh1) {
+				if (vh1->lserv_wsi == wsi)
+					vh1->lserv_wsi = NULL;
+				vh1 = vh1->vhost_next;
+			}
+		}
+		vh = vh->vhost_next;
+	}
+
+	context->deprecated = 1;
+	context->deprecation_cb = cb;
+}
+
+LWS_VISIBLE LWS_EXTERN int
+lws_context_is_deprecated(struct lws_context *context)
+{
+	return context->deprecated;
+}
+
+LWS_VISIBLE void
+lws_context_destroy2(struct lws_context *context);
+
 LWS_VISIBLE void
 lws_context_destroy(struct lws_context *context)
 {
 	const struct lws_protocols *protocol = NULL;
 	struct lws_context_per_thread *pt;
-	struct lws_vhost *vh = NULL, *vh1;
+	struct lws_vhost *vh = NULL;
 	struct lws wsi;
 	int n, m;
 
-	lwsl_notice("%s\n", __func__);
-
-	if (!context)
+	if (!context) {
+		lwsl_notice("%s: ctx %p\n", __func__, context);
+		return;
+	}
+	if (context->being_destroyed1) {
+		lwsl_notice("%s: ctx %p: already being destroyed\n", __func__, context);
 		return;
+	}
+
+	lwsl_notice("%s: ctx %p\n", __func__, context);
 
 	m = context->count_threads;
 	context->being_destroyed = 1;
+	context->being_destroyed1 = 1;
 
 	memset(&wsi, 0, sizeof(wsi));
 	wsi.context = context;
@@ -846,6 +980,7 @@ lws_context_destroy(struct lws_context *context)
 		}
 		lws_pt_mutex_destroy(pt);
 	}
+
 	/*
 	 * give all extensions a chance to clean up any per-context
 	 * allocations they might have made
@@ -895,12 +1030,30 @@ lws_context_destroy(struct lws_context *context)
 			lws_free(pt->http_header_data);
 	}
 	lws_plat_context_early_destroy(context);
-	lws_ssl_context_destroy(context);
 
 	if (context->pt[0].fds)
 		lws_free_set_NULL(context->pt[0].fds);
 
-	/* free all the vhost allocations */
+	if (!LWS_LIBUV_ENABLED(context))
+		lws_context_destroy2(context);
+}
+
+/*
+ * call the second one after the event loop has been shut down cleanly
+ */
+
+LWS_VISIBLE void
+lws_context_destroy2(struct lws_context *context)
+{
+	const struct lws_protocols *protocol = NULL;
+	struct lws_vhost *vh = NULL, *vh1;
+	int n;
+
+	lwsl_notice("%s: ctx %p\n", __func__, context);
+
+	/*
+	 * free all the per-vhost allocations
+	 */
 
 	vh = context->vhost_list;
 	while (vh) {
@@ -910,6 +1063,7 @@ lws_context_destroy(struct lws_context *context)
 			while (n < vh->count_protocols) {
 				if (vh->protocol_vh_privs &&
 				    vh->protocol_vh_privs[n]) {
+					// lwsl_notice("   %s: freeing per-vhost protocol data %p\n", __func__, vh->protocol_vh_privs[n]);
 					lws_free(vh->protocol_vh_privs[n]);
 					vh->protocol_vh_privs[n] = NULL;
 				}
@@ -924,6 +1078,11 @@ lws_context_destroy(struct lws_context *context)
 #ifdef LWS_WITH_PLUGINS
 		if (context->plugin_list)
 			lws_free((void *)vh->protocols);
+#else
+		if (vh->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
+			lws_free((void *)vh->protocols);
+#endif
+#ifdef LWS_WITH_PLUGINS
 #ifndef LWS_NO_EXTENSIONS
 		if (context->plugin_extension_count)
 			lws_free((void *)vh->extensions);
@@ -939,7 +1098,12 @@ lws_context_destroy(struct lws_context *context)
 		vh = vh1;
 	}
 
+	lws_ssl_context_destroy(context);
 	lws_plat_context_late_destroy(context);
 
+	if (context->external_baggage_free_on_destroy)
+		free(context->external_baggage_free_on_destroy);
+
+
 	lws_free(context);
 }

+ 43 - 38
EVSE/GPL/libwebsockets-v2.1-stable/lib/daemonize.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/daemonize.c

@@ -45,28 +45,31 @@ child_handler(int signum)
 		break;
 
 	case SIGUSR1: /* positive confirmation we daemonized well */
-		/* Create the lock file as the current user */
-
-		fd = open(lock_path, O_TRUNC | O_RDWR | O_CREAT, 0640);
-		if (fd < 0) {
-			fprintf(stderr,
-			   "unable to create lock file %s, code=%d (%s)\n",
-				lock_path, errno, strerror(errno));
-			exit(5);
+
+		if (lock_path) {
+			/* Create the lock file as the current user */
+
+			fd = open(lock_path, O_TRUNC | O_RDWR | O_CREAT, 0640);
+			if (fd < 0) {
+				fprintf(stderr,
+				   "unable to create lock file %s, code=%d (%s)\n",
+					lock_path, errno, strerror(errno));
+				exit(0);
+			}
+			len = sprintf(sz, "%u", pid_daemon);
+			sent = write(fd, sz, len);
+			if (sent != len)
+				fprintf(stderr,
+				  "unable to write pid to lock file %s, code=%d (%s)\n",
+						     lock_path, errno, strerror(errno));
+
+			close(fd);
 		}
-		len = sprintf(sz, "%u", pid_daemon);
-		sent = write(fd, sz, len);
-		if (sent != len)
-			fprintf(stderr,
-			  "unable to write pid to lock file %s, code=%d (%s)\n",
-					     lock_path, errno, strerror(errno));
-
-		close(fd);
 		exit(0);
 		//!!(sent == len));
 
 	case SIGCHLD: /* daemonization failed */
-		exit(6);
+		exit(0);
 		break;
 	}
 }
@@ -102,32 +105,34 @@ lws_daemonize(const char *_lock_path)
 //	if (getppid() == 1)
 //		return 1;
 
-	fd = open(_lock_path, O_RDONLY);
-	if (fd >= 0) {
-		n = read(fd, buf, sizeof(buf));
-		close(fd);
-		if (n) {
-			n = atoi(buf);
-			ret = kill(n, 0);
-			if (ret >= 0) {
+	if (_lock_path) {
+		fd = open(_lock_path, O_RDONLY);
+		if (fd >= 0) {
+			n = read(fd, buf, sizeof(buf));
+			close(fd);
+			if (n) {
+				n = atoi(buf);
+				ret = kill(n, 0);
+				if (ret >= 0) {
+					fprintf(stderr,
+					     "Daemon already running from pid %d\n", n);
+					exit(1);
+				}
 				fprintf(stderr,
-				     "Daemon already running from pid %d\n", n);
-				exit(1);
+				    "Removing stale lock file %s from dead pid %d\n",
+									 _lock_path, n);
+				unlink(lock_path);
 			}
-			fprintf(stderr,
-			    "Removing stale lock file %s from dead pid %d\n",
-								 _lock_path, n);
-			unlink(lock_path);
 		}
-	}
 
-	n = strlen(_lock_path) + 1;
-	lock_path = lws_malloc(n);
-	if (!lock_path) {
-		fprintf(stderr, "Out of mem in lws_daemonize\n");
-		return 1;
+		n = strlen(_lock_path) + 1;
+		lock_path = lws_malloc(n);
+		if (!lock_path) {
+			fprintf(stderr, "Out of mem in lws_daemonize\n");
+			return 1;
+		}
+		strcpy(lock_path, _lock_path);
 	}
-	strcpy(lock_path, _lock_path);
 
 	/* Trap signals that we expect to receive */
 	signal(SIGCHLD, child_handler);	/* died */

+ 4 - 3
EVSE/GPL/libwebsockets-v2.1-stable/lib/extension-permessage-deflate.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/extension-permessage-deflate.c

@@ -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;
 		}
@@ -303,9 +303,10 @@ lws_extension_callback_pm_deflate(struct lws_context *context,
 		priv->count_rx_between_fin += eff_buf->token_len;
 
 		lwsl_ext("  %s: RX leaving with new effbuff len %d, "
-			 "ret %d, rx.avail_in=%d, TOTAL RX since FIN %d\n",
+			 "ret %d, rx.avail_in=%d, TOTAL RX since FIN %lu\n",
 			 __func__, eff_buf->token_len, priv->rx_held_valid,
-			 priv->rx.avail_in, priv->count_rx_between_fin);
+			 priv->rx.avail_in,
+			 (unsigned long)priv->count_rx_between_fin);
 
 		if (was_fin) {
 			priv->count_rx_between_fin = 0;

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/extension-permessage-deflate.h → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/extension-permessage-deflate.h


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/extension.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/extension.c


+ 669 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/fops-zip.c

@@ -0,0 +1,669 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Original code used in this source file:
+ *
+ * https://github.com/PerBothner/DomTerm.git @912add15f3d0aec
+ *
+ * ./lws-term/io.c
+ * ./lws-term/junzip.c
+ *
+ * Copyright (C) 2017  Per Bothner <per@bothner.com>
+ *
+ * MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * ( copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ * lws rewrite:
+ *
+ * Copyright (C) 2017  Andy Green <andy@warmcat.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  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.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "private-libwebsockets.h"
+
+#include <zlib.h>
+
+/*
+ * This code works with zip format containers which may have files compressed
+ * with gzip deflate (type 8) or store uncompressed (type 0).
+ *
+ * Linux zip produces such zipfiles by default, eg
+ *
+ *  $ zip ../myzip.zip file1 file2 file3
+ */
+
+#define ZIP_COMPRESSION_METHOD_STORE 0
+#define ZIP_COMPRESSION_METHOD_DEFLATE 8
+
+typedef struct {
+	lws_filepos_t		filename_start;
+	uint32_t		crc32;
+	uint32_t		comp_size;
+	uint32_t		uncomp_size;
+	uint32_t		offset;
+	uint32_t		mod_time;
+	uint16_t		filename_len;
+	uint16_t		extra;
+	uint16_t		method;
+	uint16_t		file_com_len;
+} lws_fops_zip_hdr_t;
+
+typedef struct {
+	struct lws_fop_fd	fop_fd; /* MUST BE FIRST logical fop_fd into
+	 	 	 	 	 * file inside zip: fops_zip fops */
+	lws_fop_fd_t		zip_fop_fd; /* logical fop fd on to zip file
+	 	 	 	 	     * itself: using platform fops */
+	lws_fops_zip_hdr_t	hdr;
+	z_stream		inflate;
+	lws_filepos_t		content_start;
+	lws_filepos_t		exp_uncomp_pos;
+	union {
+		uint8_t		trailer8[8];
+		uint32_t	trailer32[2];
+	} u;
+	uint8_t			rbuf[128]; /* decompression chunk size */
+	int			entry_count;
+
+	unsigned int		decompress:1; /* 0 = direct from file */
+	unsigned int		add_gzip_container:1;
+} *lws_fops_zip_t;
+
+struct lws_plat_file_ops fops_zip;
+#define fop_fd_to_priv(FD) ((lws_fops_zip_t)(FD))
+
+static const uint8_t hd[] = { 31, 139, 8, 0, 0, 0, 0, 0, 0, 3 };
+
+enum {
+	ZC_SIGNATURE				= 0,
+	ZC_VERSION_MADE_BY 			= 4,
+	ZC_VERSION_NEEDED_TO_EXTRACT 		= 6,
+	ZC_GENERAL_PURPOSE_BIT_FLAG 		= 8,
+	ZC_COMPRESSION_METHOD 			= 10,
+	ZC_LAST_MOD_FILE_TIME 			= 12,
+	ZC_LAST_MOD_FILE_DATE 			= 14,
+	ZC_CRC32 				= 16,
+	ZC_COMPRESSED_SIZE 			= 20,
+	ZC_UNCOMPRESSED_SIZE 			= 24,
+	ZC_FILE_NAME_LENGTH 			= 28,
+	ZC_EXTRA_FIELD_LENGTH 			= 30,
+
+	ZC_FILE_COMMENT_LENGTH 			= 32,
+	ZC_DISK_NUMBER_START 			= 34,
+	ZC_INTERNAL_FILE_ATTRIBUTES 		= 36,
+	ZC_EXTERNAL_FILE_ATTRIBUTES 		= 38,
+	ZC_REL_OFFSET_LOCAL_HEADER 		= 42,
+	ZC_DIRECTORY_LENGTH 			= 46,
+
+	ZE_SIGNATURE_OFFSET 			= 0,
+	ZE_DESK_NUMBER 				= 4,
+	ZE_CENTRAL_DIRECTORY_DISK_NUMBER 	= 6,
+	ZE_NUM_ENTRIES_THIS_DISK 		= 8,
+	ZE_NUM_ENTRIES 				= 10,
+	ZE_CENTRAL_DIRECTORY_SIZE 		= 12,
+	ZE_CENTRAL_DIR_OFFSET 			= 16,
+	ZE_ZIP_COMMENT_LENGTH 			= 20,
+	ZE_DIRECTORY_LENGTH 			= 22,
+
+	ZL_REL_OFFSET_CONTENT			= 28,
+	ZL_HEADER_LENGTH			= 30,
+
+	LWS_FZ_ERR_SEEK_END_RECORD		= 1,
+	LWS_FZ_ERR_READ_END_RECORD,
+	LWS_FZ_ERR_END_RECORD_MAGIC,
+	LWS_FZ_ERR_END_RECORD_SANITY,
+	LWS_FZ_ERR_CENTRAL_SEEK,
+	LWS_FZ_ERR_CENTRAL_READ,
+	LWS_FZ_ERR_CENTRAL_SANITY,
+	LWS_FZ_ERR_NAME_TOO_LONG,
+	LWS_FZ_ERR_NAME_SEEK,
+	LWS_FZ_ERR_NAME_READ,
+	LWS_FZ_ERR_CONTENT_SANITY,
+	LWS_FZ_ERR_CONTENT_SEEK,
+	LWS_FZ_ERR_SCAN_SEEK,
+	LWS_FZ_ERR_NOT_FOUND,
+	LWS_FZ_ERR_ZLIB_INIT,
+	LWS_FZ_ERR_READ_CONTENT,
+	LWS_FZ_ERR_SEEK_COMPRESSED,
+};
+
+static uint16_t
+get_u16(void *p)
+{
+	const uint8_t *c = (const uint8_t *)p;
+
+	return (uint16_t)((c[0] | (c[1] << 8)));
+}
+
+static uint32_t
+get_u32(void *p)
+{
+	const uint8_t *c = (const uint8_t *)p;
+
+	return (uint32_t)((c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)));
+}
+
+int
+lws_fops_zip_scan(lws_fops_zip_t priv, const char *name, int len)
+{
+	lws_filepos_t amount;
+	uint8_t buf[64];
+	int i;
+
+	if (lws_vfs_file_seek_end(priv->zip_fop_fd, -ZE_DIRECTORY_LENGTH) < 0)
+		return LWS_FZ_ERR_SEEK_END_RECORD;
+
+	if (lws_vfs_file_read(priv->zip_fop_fd, &amount, buf,
+			      ZE_DIRECTORY_LENGTH))
+		return LWS_FZ_ERR_READ_END_RECORD;
+
+	if (amount != ZE_DIRECTORY_LENGTH)
+		return LWS_FZ_ERR_READ_END_RECORD;
+
+	/*
+	 * We require the zip to have the last record right at the end
+	 * Linux zip always does this if no zip comment.
+	 */
+	if (buf[0] != 'P' || buf[1] != 'K' || buf[2] != 5 || buf[3] != 6)
+		return LWS_FZ_ERR_END_RECORD_MAGIC;
+
+	i = get_u16(buf + ZE_NUM_ENTRIES);
+
+	if (get_u16(buf + ZE_DESK_NUMBER) ||
+	    get_u16(buf + ZE_CENTRAL_DIRECTORY_DISK_NUMBER) ||
+	    i != get_u16(buf + ZE_NUM_ENTRIES_THIS_DISK))
+		return LWS_FZ_ERR_END_RECORD_SANITY;
+
+	/* end record is OK... look for our file in the central dir */
+
+	if (lws_vfs_file_seek_set(priv->zip_fop_fd,
+				  get_u32(buf + ZE_CENTRAL_DIR_OFFSET)) < 0)
+		return LWS_FZ_ERR_CENTRAL_SEEK;
+
+	while (i--) {
+		priv->content_start = lws_vfs_tell(priv->zip_fop_fd);
+
+		if (lws_vfs_file_read(priv->zip_fop_fd, &amount, buf,
+				      ZC_DIRECTORY_LENGTH))
+			return LWS_FZ_ERR_CENTRAL_READ;
+
+		if (amount != ZC_DIRECTORY_LENGTH)
+			return LWS_FZ_ERR_CENTRAL_READ;
+
+		if (get_u32(buf + ZC_SIGNATURE) != 0x02014B50)
+			return LWS_FZ_ERR_CENTRAL_SANITY;
+
+               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);
+		priv->hdr.filename_start = lws_vfs_tell(priv->zip_fop_fd);
+
+		priv->hdr.method = get_u16(buf + ZC_COMPRESSION_METHOD);
+		priv->hdr.crc32 = get_u32(buf + ZC_CRC32);
+		priv->hdr.comp_size = get_u32(buf + ZC_COMPRESSED_SIZE);
+		priv->hdr.uncomp_size = get_u32(buf + ZC_UNCOMPRESSED_SIZE);
+		priv->hdr.offset = get_u32(buf + ZC_REL_OFFSET_LOCAL_HEADER);
+		priv->hdr.mod_time = get_u32(buf + ZC_LAST_MOD_FILE_TIME);
+		priv->hdr.file_com_len = get_u16(buf + ZC_FILE_COMMENT_LENGTH);
+
+		if (priv->hdr.filename_len != len)
+			goto next;
+
+		if (len >= sizeof(buf) - 1)
+			return LWS_FZ_ERR_NAME_TOO_LONG;
+
+		if (priv->zip_fop_fd->fops->LWS_FOP_READ(priv->zip_fop_fd,
+							&amount, buf, len))
+			return LWS_FZ_ERR_NAME_READ;
+		if (amount != len)
+			return LWS_FZ_ERR_NAME_READ;
+
+		buf[len] = '\0';
+		lwsl_debug("check %s vs %s\n", buf, name);
+
+		if (strcmp((const char *)buf, name))
+			goto next;
+
+		/* we found a match */
+		if (lws_vfs_file_seek_set(priv->zip_fop_fd, priv->hdr.offset) < 0)
+			return LWS_FZ_ERR_NAME_SEEK;
+		if (priv->zip_fop_fd->fops->LWS_FOP_READ(priv->zip_fop_fd,
+							&amount, buf,
+							ZL_HEADER_LENGTH))
+			return LWS_FZ_ERR_NAME_READ;
+		if (amount != ZL_HEADER_LENGTH)
+			return LWS_FZ_ERR_NAME_READ;
+
+		priv->content_start = priv->hdr.offset +
+				      ZL_HEADER_LENGTH +
+				      priv->hdr.filename_len +
+				      get_u16(buf + ZL_REL_OFFSET_CONTENT);
+
+		lwsl_debug("content supposed to start at 0x%lx\n",
+                          (unsigned long)priv->content_start);
+
+		if (priv->content_start > priv->zip_fop_fd->len)
+			return LWS_FZ_ERR_CONTENT_SANITY;
+
+		if (lws_vfs_file_seek_set(priv->zip_fop_fd,
+					  priv->content_start) < 0)
+			return LWS_FZ_ERR_CONTENT_SEEK;
+
+		/* we are aligned at the start of the content */
+
+		priv->exp_uncomp_pos = 0;
+
+		return 0;
+
+next:
+		if (i && lws_vfs_file_seek_set(priv->zip_fop_fd,
+					       priv->content_start +
+					       ZC_DIRECTORY_LENGTH +
+					       priv->hdr.filename_len +
+					       priv->hdr.extra +
+					       priv->hdr.file_com_len) < 0)
+			return LWS_FZ_ERR_SCAN_SEEK;
+	}
+
+	return LWS_FZ_ERR_NOT_FOUND;
+}
+
+static int
+lws_fops_zip_reset_inflate(lws_fops_zip_t priv)
+{
+	if (priv->decompress)
+		inflateEnd(&priv->inflate);
+
+	priv->inflate.zalloc = Z_NULL;
+	priv->inflate.zfree = Z_NULL;
+	priv->inflate.opaque = Z_NULL;
+	priv->inflate.avail_in = 0;
+	priv->inflate.next_in = Z_NULL;
+
+	if (inflateInit2(&priv->inflate, -MAX_WBITS) != Z_OK) {
+		lwsl_err("inflate init failed\n");
+		return LWS_FZ_ERR_ZLIB_INIT;
+	}
+
+	if (lws_vfs_file_seek_set(priv->zip_fop_fd, priv->content_start) < 0)
+		return LWS_FZ_ERR_CONTENT_SEEK;
+
+	priv->exp_uncomp_pos = 0;
+
+	return 0;
+}
+
+static lws_fop_fd_t
+lws_fops_zip_open(const struct lws_plat_file_ops *fops, const char *vfs_path,
+		  const char *vpath, lws_fop_flags_t *flags)
+{
+	lws_fop_flags_t local_flags = 0;
+	lws_fops_zip_t priv;
+	char rp[192];
+	int m;
+
+	/*
+	 * vpath points at the / after the fops signature in vfs_path, eg
+	 * with a vfs_path "/var/www/docs/manual.zip/index.html", vpath
+	 * will come pointing at "/index.html"
+	 */
+
+	priv = lws_zalloc(sizeof(*priv));
+	if (!priv)
+		return NULL;
+
+	priv->fop_fd.fops = &fops_zip;
+
+	m = sizeof(rp) - 1;
+	if ((vpath - vfs_path - 1) < m)
+		m = vpath - vfs_path - 1;
+	strncpy(rp, vfs_path, m);
+	rp[m] = '\0';
+
+	/* open the zip file itself using the incoming fops, not fops_zip */
+
+	priv->zip_fop_fd = fops->LWS_FOP_OPEN(fops, rp, NULL, &local_flags);
+	if (!priv->zip_fop_fd) {
+		lwsl_err("unable to open zip %s\n", rp);
+		goto bail1;
+	}
+
+	if (*vpath == '/')
+		vpath++;
+
+	m = lws_fops_zip_scan(priv, vpath, strlen(vpath));
+	if (m) {
+		lwsl_err("unable to find record matching '%s' %d\n", vpath, m);
+		goto bail2;
+	}
+
+	/* the directory metadata tells us modification time, so pass it on */
+	priv->fop_fd.mod_time = priv->hdr.mod_time;
+	*flags |= LWS_FOP_FLAG_MOD_TIME_VALID | LWS_FOP_FLAG_VIRTUAL;
+	priv->fop_fd.flags = *flags;
+
+	/* The zip fop_fd is left pointing at the start of the content.
+	 *
+	 * 1) Content could be uncompressed (STORE), and we can always serve
+	 *    that directly
+	 *
+	 * 2) Content could be compressed (GZIP), and the client can handle
+	 *    receiving GZIP... we can wrap it in a GZIP header and trailer
+	 *    and serve the content part directly.  The flag indicating we
+	 *    are providing GZIP directly is set so lws will send the right
+	 *    headers.
+	 *
+	 * 3) Content could be compressed (GZIP) but the client can't handle
+	 *    receiving GZIP... we can decompress it and serve as it is
+	 *    inflated piecemeal.
+	 *
+	 * 4) Content may be compressed some unknown way... fail
+	 *
+	 */
+	if (priv->hdr.method == ZIP_COMPRESSION_METHOD_STORE) {
+		/*
+		 * it is stored uncompressed, leave it indicated as
+		 * uncompressed, and just serve it from inside the
+		 * zip with no gzip container;
+		 */
+
+		lwsl_info("direct zip serving (stored)\n");
+
+		priv->fop_fd.len = priv->hdr.uncomp_size;
+
+		return &priv->fop_fd;
+	}
+
+	if ((*flags & LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP) &&
+	    priv->hdr.method == ZIP_COMPRESSION_METHOD_DEFLATE) {
+
+		/*
+		 * We can serve the gzipped file contents directly as gzip
+		 * from inside the zip container; client says it is OK.
+		 *
+		 * To convert to standalone gzip, we have to add a 10-byte
+		 * constant header and a variable 8-byte trailer around the
+		 * content.
+		 *
+		 * The 8-byte trailer is prepared now and held in the priv.
+		 */
+
+		lwsl_info("direct zip serving (gzipped)\n");
+
+		priv->fop_fd.len = sizeof(hd) + priv->hdr.comp_size +
+				   sizeof(priv->u);
+
+		if (lws_is_be()) {
+			uint8_t *p = priv->u.trailer8;
+
+			*p++ = (uint8_t)priv->hdr.crc32;
+			*p++ = (uint8_t)(priv->hdr.crc32 >> 8);
+			*p++ = (uint8_t)(priv->hdr.crc32 >> 16);
+			*p++ = (uint8_t)(priv->hdr.crc32 >> 24);
+			*p++ = (uint8_t)priv->hdr.uncomp_size;
+			*p++ = (uint8_t)(priv->hdr.uncomp_size >> 8);
+			*p++ = (uint8_t)(priv->hdr.uncomp_size >> 16);
+			*p   = (uint8_t)(priv->hdr.uncomp_size >> 24);
+		} else {
+			priv->u.trailer32[0] = priv->hdr.crc32;
+			priv->u.trailer32[1] = priv->hdr.uncomp_size;
+		}
+
+		*flags |= LWS_FOP_FLAG_COMPR_IS_GZIP;
+		priv->fop_fd.flags = *flags;
+		priv->add_gzip_container = 1;
+
+		return &priv->fop_fd;
+	}
+
+	if (priv->hdr.method == ZIP_COMPRESSION_METHOD_DEFLATE) {
+
+		/* we must decompress it to serve it */
+
+		lwsl_info("decompressed zip serving\n");
+
+		priv->fop_fd.len = priv->hdr.uncomp_size;
+
+		if (lws_fops_zip_reset_inflate(priv)) {
+			lwsl_err("inflate init failed\n");
+			goto bail2;
+		}
+
+		priv->decompress = 1;
+
+		return &priv->fop_fd;
+	}
+
+	/* we can't handle it ... */
+
+	lwsl_err("zipped file %s compressed in unknown way (%d)\n", vfs_path,
+		 priv->hdr.method);
+
+bail2:
+	lws_vfs_file_close(&priv->zip_fop_fd);
+bail1:
+	free(priv);
+
+	return NULL;
+}
+
+/* ie, we are closing the fop_fd for the file inside the gzip */
+
+static int
+lws_fops_zip_close(lws_fop_fd_t *fd)
+{
+	lws_fops_zip_t priv = fop_fd_to_priv(*fd);
+
+	if (priv->decompress)
+		inflateEnd(&priv->inflate);
+
+	lws_vfs_file_close(&priv->zip_fop_fd); /* close the gzip fop_fd */
+
+	free(priv);
+	*fd = NULL;
+
+	return 0;
+}
+
+static lws_fileofs_t
+lws_fops_zip_seek_cur(lws_fop_fd_t fd, lws_fileofs_t offset_from_cur_pos)
+{
+	fd->pos += offset_from_cur_pos;
+
+	return fd->pos;
+}
+
+static int
+lws_fops_zip_read(lws_fop_fd_t fd, lws_filepos_t *amount, uint8_t *buf,
+		  lws_filepos_t len)
+{
+	lws_fops_zip_t priv = fop_fd_to_priv(fd);
+	lws_filepos_t ramount, rlen, cur = lws_vfs_tell(fd);
+	int ret;
+
+	if (priv->decompress) {
+
+		if (priv->exp_uncomp_pos != fd->pos) {
+			/*
+			 *  there has been a seek in the uncompressed fop_fd
+			 * we have to restart the decompression and loop eating
+			 * the decompressed data up to the seek point
+			 */
+			lwsl_info("seek in decompressed\n");
+
+			lws_fops_zip_reset_inflate(priv);
+
+			while (priv->exp_uncomp_pos != fd->pos) {
+				rlen = len;
+				if (rlen > fd->pos - priv->exp_uncomp_pos)
+					rlen = fd->pos - priv->exp_uncomp_pos;
+				if (lws_fops_zip_read(fd, amount, buf, rlen))
+					return LWS_FZ_ERR_SEEK_COMPRESSED;
+			}
+			*amount = 0;
+		}
+
+		priv->inflate.avail_out = len;
+		priv->inflate.next_out = buf;
+
+spin:
+		if (!priv->inflate.avail_in) {
+			rlen = sizeof(priv->rbuf);
+			if (rlen > priv->hdr.comp_size -
+				   (cur - priv->content_start))
+				rlen = priv->hdr.comp_size -
+				       (priv->hdr.comp_size -
+					priv->content_start);
+
+			if (priv->zip_fop_fd->fops->LWS_FOP_READ(
+					priv->zip_fop_fd, &ramount, priv->rbuf,
+					rlen))
+				return LWS_FZ_ERR_READ_CONTENT;
+
+			cur += ramount;
+
+			priv->inflate.avail_in = ramount;
+			priv->inflate.next_in = priv->rbuf;
+		}
+
+		ret = inflate(&priv->inflate, Z_NO_FLUSH);
+		if (ret == Z_STREAM_ERROR)
+			return ret;
+
+		switch (ret) {
+		case Z_NEED_DICT:
+			ret = Z_DATA_ERROR;
+			/* and fall through */
+		case Z_DATA_ERROR:
+		case Z_MEM_ERROR:
+
+			return ret;
+		}
+
+		if (!priv->inflate.avail_in && priv->inflate.avail_out &&
+		     cur != priv->content_start + priv->hdr.comp_size)
+			goto spin;
+
+		*amount = len - priv->inflate.avail_out;
+
+		priv->exp_uncomp_pos += *amount;
+		fd->pos += *amount;
+
+		return 0;
+	}
+
+	if (priv->add_gzip_container) {
+
+		lwsl_info("%s: gzip + container\n", __func__);
+		*amount = 0;
+
+		/* place the canned header at the start */
+
+		if (len && fd->pos < sizeof(hd)) {
+			rlen = sizeof(hd) - fd->pos;
+			if (rlen > len)
+				rlen = len;
+			/* provide stuff from canned header */
+			memcpy(buf, hd + fd->pos, rlen);
+			fd->pos += rlen;
+			buf += rlen;
+			len -= rlen;
+			*amount += rlen;
+		}
+
+		/* serve gzipped data direct from zipfile */
+
+		if (len && fd->pos >= sizeof(hd) &&
+		    fd->pos < priv->hdr.comp_size + sizeof(hd)) {
+
+			rlen = priv->hdr.comp_size - (priv->zip_fop_fd->pos -
+						      priv->content_start);
+			if (rlen > len)
+				rlen = len;
+
+			if (rlen &&
+			    priv->zip_fop_fd->pos < (priv->hdr.comp_size +
+					    	     priv->content_start)) {
+				if (lws_vfs_file_read(priv->zip_fop_fd,
+						      &ramount, buf, rlen))
+					return LWS_FZ_ERR_READ_CONTENT;
+				*amount += ramount;
+				fd->pos += ramount; // virtual pos
+				buf += ramount;
+				len -= ramount;
+			}
+		}
+
+		/* place the prepared trailer at the end */
+
+		if (len && fd->pos >= priv->hdr.comp_size + sizeof(hd) &&
+		    fd->pos < priv->hdr.comp_size + sizeof(hd) +
+		    	      sizeof(priv->u)) {
+			cur = fd->pos - priv->hdr.comp_size - sizeof(hd);
+			rlen = sizeof(priv->u) - cur;
+			if (rlen > len)
+				rlen = len;
+
+			memcpy(buf, priv->u.trailer8 + cur, rlen);
+
+			*amount += rlen;
+			fd->pos += rlen;
+		}
+
+		return 0;
+	}
+
+	lwsl_info("%s: store\n", __func__);
+
+	if (len > priv->hdr.uncomp_size - (cur - priv->content_start))
+		len = priv->hdr.comp_size - (priv->hdr.comp_size -
+					     priv->content_start);
+
+	if (priv->zip_fop_fd->fops->LWS_FOP_READ(priv->zip_fop_fd,
+						 amount, buf, len))
+		return LWS_FZ_ERR_READ_CONTENT;
+
+	return 0;
+}
+
+struct lws_plat_file_ops fops_zip = {
+	lws_fops_zip_open,
+	lws_fops_zip_close,
+	lws_fops_zip_seek_cur,
+	lws_fops_zip_read,
+	NULL,
+	{ { ".zip/", 5 }, { ".jar/", 5 }, { ".war/", 5 } },
+	NULL,
+};

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/getifaddrs.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/getifaddrs.c


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/getifaddrs.h → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/getifaddrs.h


+ 7 - 2
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/handshake.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/handshake.c

@@ -121,6 +121,11 @@ lws_read(struct lws *wsi, unsigned char *buf, size_t len)
 			/* Handshake indicates this session is done. */
 			goto bail;
 
+		/* we might have transitioned to RAW */
+		if (wsi->mode == LWSCM_RAW)
+			 /* we gave the read buffer to RAW handler already */
+			goto read_ok;
+
 		/*
 		 * It's possible that we've exhausted our data already, or
 		 * rx flow control has stopped us dealing with this early,
@@ -129,7 +134,7 @@ lws_read(struct lws *wsi, unsigned char *buf, size_t len)
 		 * appropriately:
 		 */
 		len -= (buf - last_char);
-		lwsl_debug("%s: thinks we have used %d\n", __func__, len);
+		lwsl_debug("%s: thinks we have used %ld\n", __func__, (long)len);
 
 		if (!wsi->hdr_parsing_completed)
 			/* More header content on the way */
@@ -245,7 +250,7 @@ postbody_completion:
 
 read_ok:
 	/* Nothing more to do for now */
-	lwsl_info("%s: read_ok, used %d\n", __func__, buf - oldbuf);
+	lwsl_info("%s: read_ok, used %ld\n", __func__, (long)(buf - oldbuf));
 
 	return buf - oldbuf;
 

+ 14 - 15
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/header.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/header.c

@@ -143,16 +143,17 @@ STORE_IN_ROM static const char * const err500[] = {
 };
 
 int
-lws_add_http_header_status(struct lws *wsi, unsigned int code,
+lws_add_http_header_status(struct lws *wsi, unsigned int _code,
 			   unsigned char **p, unsigned char *end)
 {
-	const struct lws_protocol_vhost_options *headers;
-	unsigned char code_and_desc[60];
-	const char *description = "", *p1;
-	int n;
 	STORE_IN_ROM static const char * const hver[] = {
 		"HTTP/1.0", "HTTP/1.1", "HTTP/2"
 	};
+	const struct lws_protocol_vhost_options *headers;
+	unsigned int code = _code & LWSAHH_CODE_MASK;
+	const char *description = "", *p1;
+	unsigned char code_and_desc[60];
+	int n;
 
 #ifdef LWS_WITH_ACCESS_LOG
 	wsi->access_log.response = code;
@@ -181,11 +182,9 @@ lws_add_http_header_status(struct lws *wsi, unsigned int code,
 	else
 		p1 = hver[0];
 
-	n = sprintf((char *)code_and_desc, "%s %u %s",
-		    p1, code, description);
+	n = sprintf((char *)code_and_desc, "%s %u %s", p1, code, description);
 
-	if (lws_add_http_header_by_name(wsi, NULL, code_and_desc,
-					   n, p, end))
+	if (lws_add_http_header_by_name(wsi, NULL, code_and_desc, n, p, end))
 		return 1;
 
 	headers = wsi->vhost->headers;
@@ -199,12 +198,12 @@ lws_add_http_header_status(struct lws *wsi, unsigned int code,
 		headers = headers->next;
 	}
 
-	if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_SERVER,
-					 (unsigned char *)
-					 	 wsi->context->server_string,
-					 wsi->context->server_string_len,
-					 p, end))
-		return 1;
+	if (wsi->context->server_string &&
+	    !(_code & LWSAHH_FLAG_NO_SERVER_NAME))
+		if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_SERVER,
+				(unsigned char *)wsi->context->server_string,
+				wsi->context->server_string_len, p, end))
+			return 1;
 
 	if (wsi->vhost->options & LWS_SERVER_OPTION_STS)
 		if (lws_add_http_header_by_name(wsi, (unsigned char *)

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/hpack.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/hpack.c


+ 3 - 3
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/http2.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/http2.c

@@ -169,14 +169,14 @@ 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);
 
 	if (type == LWS_HTTP2_FRAME_TYPE_DATA) {
 		if (wsi->u.http2.tx_credit < len)
 			lwsl_err("%s: %p: sending payload len %d"
-				 " but tx_credit only %d!\n", len,
+				 " but tx_credit only %d!\n", __func__, wsi, len,
 				 wsi->u.http2.tx_credit);
 		wsi->u.http2.tx_credit -= len;
 	}
@@ -476,7 +476,7 @@ int lws_http2_do_pps_send(struct lws_context *context, struct lws *wsi)
 		if (wsi->state == LWSS_HTTP2_ESTABLISHED_PRE_SETTINGS) {
 			wsi->state = LWSS_HTTP2_ESTABLISHED;
 
-			wsi->u.http.fd = LWS_INVALID_FILE;
+			wsi->u.http.fop_fd = NULL;
 
 			if (lws_is_ssl(lws_http2_get_network_wsi(wsi))) {
 				lwsl_info("skipping nonexistent ssl upgrade headers\n");

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/huftable.h → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/huftable.h


+ 91 - 7
EVSE/GPL/libwebsockets-v2.1-stable/lib/lejp-conf.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lejp-conf.c

@@ -37,6 +37,9 @@ static const char * const paths_global[] = {
 	"global.server-string",
 	"global.plugin-dir",
 	"global.ws-pingpong-secs",
+	"global.timeout-secs",
+	"global.reject-service-keywords[].*",
+	"global.reject-service-keywords[]",
 };
 
 enum lejp_global_paths {
@@ -47,6 +50,9 @@ enum lejp_global_paths {
 	LEJPGP_SERVER_STRING,
 	LEJPGP_PLUGIN_DIR,
 	LWJPGP_PINGPONG_SECS,
+	LWJPGP_TIMEOUT_SECS,
+	LWJPGP_REJECT_SERVICE_KEYWORDS_NAME,
+	LWJPGP_REJECT_SERVICE_KEYWORDS
 };
 
 static const char * const paths_vhosts[] = {
@@ -71,6 +77,7 @@ static const char * const paths_vhosts[] = {
 	"vhosts[].mounts[].cache-max-age",
 	"vhosts[].mounts[].cache-reuse",
 	"vhosts[].mounts[].cache-revalidate",
+	"vhosts[].mounts[].basic-auth",
 	"vhosts[].mounts[].cache-intermediaries",
 	"vhosts[].mounts[].extra-mimetypes.*",
 	"vhosts[].mounts[].interpret.*",
@@ -88,6 +95,10 @@ static const char * const paths_vhosts[] = {
 	"vhosts[].mounts[].pmo[].*",
 	"vhosts[].headers[].*",
 	"vhosts[].headers[]",
+	"vhosts[].client-ssl-key",
+	"vhosts[].client-ssl-cert",
+	"vhosts[].client-ssl-ca",
+	"vhosts[].client-ssl-ciphers",
 };
 
 enum lejp_vhost_paths {
@@ -112,6 +123,7 @@ enum lejp_vhost_paths {
 	LEJPVP_MOUNT_CACHE_MAX_AGE,
 	LEJPVP_MOUNT_CACHE_REUSE,
 	LEJPVP_MOUNT_CACHE_REVALIDATE,
+	LEJPVP_MOUNT_BASIC_AUTH,
 	LEJPVP_MOUNT_CACHE_INTERMEDIARIES,
 	LEJPVP_MOUNT_EXTRA_MIMETYPES,
 	LEJPVP_MOUNT_INTERPRET,
@@ -129,6 +141,10 @@ enum lejp_vhost_paths {
 	LEJPVP_PMO,
 	LEJPVP_HEADERS_NAME,
 	LEJPVP_HEADERS,
+	LEJPVP_CLIENT_SSL_KEY,
+	LEJPVP_CLIENT_SSL_CERT,
+	LEJPVP_CLIENT_SSL_CA,
+	LEJPVP_CLIENT_CIPHERS,
 };
 
 static const char * const parser_errs[] = {
@@ -209,11 +225,31 @@ static char
 lejp_globals_cb(struct lejp_ctx *ctx, char reason)
 {
 	struct jpargs *a = (struct jpargs *)ctx->user;
+	struct lws_protocol_vhost_options *rej;
+	int n;
 
 	/* we only match on the prepared path strings */
 	if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match)
 		return 0;
 
+	/* this catches, eg, vhosts[].headers[].xxx */
+	if (reason == LEJPCB_VAL_STR_END &&
+	    ctx->path_match == LWJPGP_REJECT_SERVICE_KEYWORDS_NAME + 1) {
+		rej = lwsws_align(a);
+		a->p += sizeof(*rej);
+
+		n = lejp_get_wildcard(ctx, 0, a->p, a->end - a->p);
+		rej->next = a->info->reject_service_keywords;
+		a->info->reject_service_keywords = rej;
+		rej->name = a->p;
+		 lwsl_notice("  adding rej %s=%s\n", a->p, ctx->buf);
+		a->p += n - 1;
+		*(a->p++) = '\0';
+		rej->value = a->p;
+		rej->options = NULL;
+		goto dostring;
+	}
+
 	switch (ctx->path_match - 1) {
 	case LEJPGP_UID:
 		a->info->uid = atoi(ctx->buf);
@@ -243,10 +279,15 @@ lejp_globals_cb(struct lejp_ctx *ctx, char reason)
 		a->info->ws_ping_pong_interval = atoi(ctx->buf);
 		return 0;
 
+	case LWJPGP_TIMEOUT_SECS:
+		a->info->timeout_secs = atoi(ctx->buf);
+		return 0;
+
 	default:
 		return 0;
 	}
 
+dostring:
 	a->p += lws_snprintf(a->p, a->end - a->p, "%s", ctx->buf);
 	*(a->p)++ = '\0';
 
@@ -280,6 +321,22 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
 		a->info->ssl_cert_filepath = NULL;
 		a->info->ssl_private_key_filepath = NULL;
 		a->info->ssl_ca_filepath = NULL;
+		a->info->client_ssl_cert_filepath = NULL;
+		a->info->client_ssl_private_key_filepath = NULL;
+		a->info->client_ssl_ca_filepath = NULL;
+		a->info->client_ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
+			"ECDHE-RSA-AES256-GCM-SHA384:"
+			"DHE-RSA-AES256-GCM-SHA384:"
+			"ECDHE-RSA-AES256-SHA384:"
+			"HIGH:!aNULL:!eNULL:!EXPORT:"
+			"!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:"
+			"!SHA1:!DHE-RSA-AES128-GCM-SHA256:"
+			"!DHE-RSA-AES128-SHA256:"
+			"!AES128-GCM-SHA256:"
+			"!AES128-SHA256:"
+			"!DHE-RSA-AES256-SHA256:"
+			"!AES256-GCM-SHA384:"
+			"!AES256-SHA256";
 		a->info->timeout_secs = 5;
 		a->info->ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
 				       "ECDHE-RSA-AES256-GCM-SHA384:"
@@ -373,7 +430,15 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
 		a->any_vhosts = 1;
 
 		if (a->enable_client_ssl) {
+			const char *cert_filepath = a->info->client_ssl_cert_filepath;
+			const char *private_key_filepath = a->info->client_ssl_private_key_filepath;
+			const char *ca_filepath = a->info->client_ssl_ca_filepath;
+			const char *cipher_list = a->info->client_ssl_cipher_list;
 			memset(a->info, 0, sizeof(*a->info));
+			a->info->client_ssl_cert_filepath = cert_filepath;
+			a->info->client_ssl_private_key_filepath = private_key_filepath;
+			a->info->client_ssl_ca_filepath = ca_filepath;
+			a->info->client_ssl_cipher_list = cipher_list;
 			a->info->options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
 			lws_init_vhost_client_ssl(a->info, vhost);
 		}
@@ -390,7 +455,8 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
 			"cgi://",
 			">http://",
 			">https://",
-			"callback://"
+			"callback://",
+			"gzip://",
 		};
 
 		if (!a->fresh_mount)
@@ -496,12 +562,18 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
 	case LEJPVP_MOUNT_CACHE_INTERMEDIARIES:
 		a->m.cache_intermediaries = arg_to_bool(ctx->buf);;
 		return 0;
+	case LEJPVP_MOUNT_BASIC_AUTH:
+		a->m.basic_auth_login_file = a->p;
+		break;
 	case LEJPVP_CGI_TIMEOUT:
 		a->m.cgi_timeout = atoi(ctx->buf);
 		return 0;
 	case LEJPVP_KEEPALIVE_TIMEOUT:
 		a->info->keepalive_timeout = atoi(ctx->buf);
 		return 0;
+	case LEJPVP_CLIENT_CIPHERS:
+		a->info->client_ssl_cipher_list = a->p;
+		break;
 	case LEJPVP_CIPHERS:
 		a->info->ssl_cipher_list = a->p;
 		break;
@@ -521,8 +593,8 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
 		a->p += n;
 		mp_cgienv->value = a->p;
 		mp_cgienv->options = NULL;
-		lwsl_notice("    adding pmo / cgi-env '%s' = '%s'\n", mp_cgienv->name,
-				mp_cgienv->value);
+		//lwsl_notice("    adding pmo / cgi-env '%s' = '%s'\n", mp_cgienv->name,
+		//		mp_cgienv->value);
 		goto dostring;
 
 	case LEJPVP_PROTOCOL_NAME_OPT:
@@ -577,6 +649,15 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
 	case LEJPVP_ENABLE_CLIENT_SSL:
 		a->enable_client_ssl = arg_to_bool(ctx->buf);
 		return 0;
+	case LEJPVP_CLIENT_SSL_KEY:
+		a->info->client_ssl_private_key_filepath = a->p;
+		break;
+	case LEJPVP_CLIENT_SSL_CERT:
+		a->info->client_ssl_cert_filepath = a->p;
+		break;
+	case LEJPVP_CLIENT_SSL_CA:
+		a->info->client_ssl_ca_filepath = a->p;
+		break;
 
 	case LEJPVP_NOIPV6:
 		if (arg_to_bool(ctx->buf))
@@ -673,10 +754,13 @@ lwsws_get_config_d(void *user, const char *d, const char * const *paths,
 	uv_dirent_t dent;
 	uv_fs_t req;
 	char path[256];
-	int ret = 0;
+	int ret = 0, ir;
 	uv_loop_t loop;
 
-	uv_loop_init(&loop);
+	ir = uv_loop_init(&loop);
+	if (ir) {
+		lwsl_err("%s: loop init failed %d\n", __func__, ir);
+	}
 
 	if (!uv_fs_scandir(&loop, &req, d, 0, NULL)) {
 		lwsl_err("Scandir on %s failed\n", d);
@@ -720,7 +804,7 @@ lwsws_get_config_d(void *user, const char *d, const char * const *paths,
 
 	n = scandir(d, &namelist, filter, alphasort);
 	if (n < 0) {
-		lwsl_err("Scandir on %d failed\n", d);
+		lwsl_err("Scandir on %s failed\n", d);
 	}
 
 	for (i = 0; i < n; i++) {
@@ -825,7 +909,7 @@ lwsws_get_config_vhosts(struct lws_context *context,
 		return 1;
 	}
 
-	lws_finalize_startup(context);
+//	lws_finalize_startup(context);
 
 	return 0;
 }

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/lejp.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lejp.c


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/lejp.h → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lejp.h


+ 3 - 0
EVSE/GPL/libwebsockets-v2.1-stable/lib/lextable-strings.h → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lextable-strings.h

@@ -94,6 +94,9 @@ STORE_IN_ROM static const char * const set[] = {
 	"x-real-ip:",
 	"http/1.0 ",
 
+	"x-forwarded-for",
+	"connect ",
+
 	"", /* not matchable */
 
 };

+ 796 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lextable.h

@@ -0,0 +1,796 @@
+/* pos 0000:   0 */    0x67 /* 'g' */, 0x40, 0x00  /* (to 0x0040 state   1) */,
+                       0x70 /* 'p' */, 0x42, 0x00  /* (to 0x0045 state   5) */,
+                       0x6F /* 'o' */, 0x51, 0x00  /* (to 0x0057 state  10) */,
+                       0x68 /* 'h' */, 0x5D, 0x00  /* (to 0x0066 state  18) */,
+                       0x63 /* 'c' */, 0x66, 0x00  /* (to 0x0072 state  23) */,
+                       0x75 /* 'u' */, 0x87, 0x00  /* (to 0x0096 state  34) */,
+                       0x73 /* 's' */, 0x9D, 0x00  /* (to 0x00AF state  48) */,
+                       0x0D /* '.' */, 0xD6, 0x00  /* (to 0x00EB state  68) */,
+                       0x61 /* 'a' */, 0x2E, 0x01  /* (to 0x0146 state 129) */,
+                       0x69 /* 'i' */, 0x6D, 0x01  /* (to 0x0188 state 163) */,
+                       0x64 /* 'd' */, 0x16, 0x02  /* (to 0x0234 state 265) */,
+                       0x72 /* 'r' */, 0x1F, 0x02  /* (to 0x0240 state 270) */,
+                       0x3A /* ':' */, 0x50, 0x02  /* (to 0x0274 state 299) */,
+                       0x65 /* 'e' */, 0xDC, 0x02  /* (to 0x0303 state 409) */,
+                       0x66 /* 'f' */, 0xF8, 0x02  /* (to 0x0322 state 425) */,
+                       0x6C /* 'l' */, 0x1A, 0x03  /* (to 0x0347 state 458) */,
+                       0x6D /* 'm' */, 0x3D, 0x03  /* (to 0x036D state 484) */,
+                       0x74 /* 't' */, 0xAC, 0x03  /* (to 0x03DF state 578) */,
+                       0x76 /* 'v' */, 0xC7, 0x03  /* (to 0x03FD state 606) */,
+                       0x77 /* 'w' */, 0xD4, 0x03  /* (to 0x040D state 614) */,
+                       0x78 /* 'x' */, 0xFB, 0x03  /* (to 0x0437 state 650) */,
+                       0x08, /* fail */
+/* pos 0040:   1 */    0xE5 /* 'e' -> */,
+/* pos 0041:   2 */    0xF4 /* 't' -> */,
+/* pos 0042:   3 */    0xA0 /* ' ' -> */,
+/* pos 0043:   4 */    0x00, 0x00                  /* - terminal marker  0 - */,
+/* pos 0045:   5 */    0x6F /* 'o' */, 0x0D, 0x00  /* (to 0x0052 state   6) */,
+                       0x72 /* 'r' */, 0x92, 0x01  /* (to 0x01DA state 211) */,
+                       0x61 /* 'a' */, 0xD4, 0x03  /* (to 0x041F state 631) */,
+                       0x75 /* 'u' */, 0xD6, 0x03  /* (to 0x0424 state 635) */,
+                       0x08, /* fail */
+/* pos 0052:   6 */    0xF3 /* 's' -> */,
+/* pos 0053:   7 */    0xF4 /* 't' -> */,
+/* pos 0054:   8 */    0xA0 /* ' ' -> */,
+/* pos 0055:   9 */    0x00, 0x01                  /* - terminal marker  1 - */,
+/* pos 0057:  10 */    0x70 /* 'p' */, 0x07, 0x00  /* (to 0x005E state  11) */,
+                       0x72 /* 'r' */, 0x4E, 0x00  /* (to 0x00A8 state  42) */,
+                       0x08, /* fail */
+/* pos 005e:  11 */    0xF4 /* 't' -> */,
+/* pos 005f:  12 */    0xE9 /* 'i' -> */,
+/* pos 0060:  13 */    0xEF /* 'o' -> */,
+/* pos 0061:  14 */    0xEE /* 'n' -> */,
+/* pos 0062:  15 */    0xF3 /* 's' -> */,
+/* pos 0063:  16 */    0xA0 /* ' ' -> */,
+/* pos 0064:  17 */    0x00, 0x02                  /* - terminal marker  2 - */,
+/* pos 0066:  18 */    0x6F /* 'o' */, 0x07, 0x00  /* (to 0x006D state  19) */,
+                       0x74 /* 't' */, 0xBC, 0x00  /* (to 0x0125 state 110) */,
+                       0x08, /* fail */
+/* pos 006d:  19 */    0xF3 /* 's' -> */,
+/* pos 006e:  20 */    0xF4 /* 't' -> */,
+/* pos 006f:  21 */    0xBA /* ':' -> */,
+/* pos 0070:  22 */    0x00, 0x03                  /* - terminal marker  3 - */,
+/* pos 0072:  23 */    0x6F /* 'o' */, 0x07, 0x00  /* (to 0x0079 state  24) */,
+                       0x61 /* 'a' */, 0x72, 0x01  /* (to 0x01E7 state 217) */,
+                       0x08, /* fail */
+/* pos 0079:  24 */    0x6E /* 'n' */, 0x07, 0x00  /* (to 0x0080 state  25) */,
+                       0x6F /* 'o' */, 0x87, 0x01  /* (to 0x0203 state 243) */,
+                       0x08, /* fail */
+/* pos 0080:  25 */    0x6E /* 'n' */, 0x07, 0x00  /* (to 0x0087 state  26) */,
+                       0x74 /* 't' */, 0x86, 0x01  /* (to 0x0209 state 248) */,
+                       0x08, /* fail */
+/* pos 0087:  26 */    0xE5 /* 'e' -> */,
+/* pos 0088:  27 */    0xE3 /* 'c' -> */,
+/* pos 0089:  28 */    0xF4 /* 't' -> */,
+/* pos 008a:  29 */    0x69 /* 'i' */, 0x07, 0x00  /* (to 0x0091 state  30) */,
+                       0x20 /* ' ' */, 0xCC, 0x03  /* (to 0x0459 state 675) */,
+                       0x08, /* fail */
+/* pos 0091:  30 */    0xEF /* 'o' -> */,
+/* pos 0092:  31 */    0xEE /* 'n' -> */,
+/* pos 0093:  32 */    0xBA /* ':' -> */,
+/* pos 0094:  33 */    0x00, 0x04                  /* - terminal marker  4 - */,
+/* pos 0096:  34 */    0x70 /* 'p' */, 0x0A, 0x00  /* (to 0x00A0 state  35) */,
+                       0x73 /* 's' */, 0x59, 0x03  /* (to 0x03F2 state 596) */,
+                       0x72 /* 'r' */, 0x91, 0x03  /* (to 0x042D state 642) */,
+                       0x08, /* fail */
+/* pos 00a0:  35 */    0xE7 /* 'g' -> */,
+/* pos 00a1:  36 */    0xF2 /* 'r' -> */,
+/* pos 00a2:  37 */    0xE1 /* 'a' -> */,
+/* pos 00a3:  38 */    0xE4 /* 'd' -> */,
+/* pos 00a4:  39 */    0xE5 /* 'e' -> */,
+/* pos 00a5:  40 */    0xBA /* ':' -> */,
+/* pos 00a6:  41 */    0x00, 0x05                  /* - terminal marker  5 - */,
+/* pos 00a8:  42 */    0xE9 /* 'i' -> */,
+/* pos 00a9:  43 */    0xE7 /* 'g' -> */,
+/* pos 00aa:  44 */    0xE9 /* 'i' -> */,
+/* pos 00ab:  45 */    0xEE /* 'n' -> */,
+/* pos 00ac:  46 */    0xBA /* ':' -> */,
+/* pos 00ad:  47 */    0x00, 0x06                  /* - terminal marker  6 - */,
+/* pos 00af:  48 */    0x65 /* 'e' */, 0x07, 0x00  /* (to 0x00B6 state  49) */,
+                       0x74 /* 't' */, 0x13, 0x03  /* (to 0x03C5 state 553) */,
+                       0x08, /* fail */
+/* pos 00b6:  49 */    0x63 /* 'c' */, 0x0A, 0x00  /* (to 0x00C0 state  50) */,
+                       0x72 /* 'r' */, 0xFC, 0x02  /* (to 0x03B5 state 539) */,
+                       0x74 /* 't' */, 0xFF, 0x02  /* (to 0x03BB state 544) */,
+                       0x08, /* fail */
+/* pos 00c0:  50 */    0xAD /* '-' -> */,
+/* pos 00c1:  51 */    0xF7 /* 'w' -> */,
+/* pos 00c2:  52 */    0xE5 /* 'e' -> */,
+/* pos 00c3:  53 */    0xE2 /* 'b' -> */,
+/* pos 00c4:  54 */    0xF3 /* 's' -> */,
+/* pos 00c5:  55 */    0xEF /* 'o' -> */,
+/* pos 00c6:  56 */    0xE3 /* 'c' -> */,
+/* pos 00c7:  57 */    0xEB /* 'k' -> */,
+/* pos 00c8:  58 */    0xE5 /* 'e' -> */,
+/* pos 00c9:  59 */    0xF4 /* 't' -> */,
+/* pos 00ca:  60 */    0xAD /* '-' -> */,
+/* pos 00cb:  61 */    0x64 /* 'd' */, 0x19, 0x00  /* (to 0x00E4 state  62) */,
+                       0x65 /* 'e' */, 0x20, 0x00  /* (to 0x00EE state  70) */,
+                       0x6B /* 'k' */, 0x29, 0x00  /* (to 0x00FA state  81) */,
+                       0x70 /* 'p' */, 0x38, 0x00  /* (to 0x010C state  88) */,
+                       0x61 /* 'a' */, 0x3F, 0x00  /* (to 0x0116 state  97) */,
+                       0x6E /* 'n' */, 0x44, 0x00  /* (to 0x011E state 104) */,
+                       0x76 /* 'v' */, 0x86, 0x01  /* (to 0x0263 state 284) */,
+                       0x6F /* 'o' */, 0x8C, 0x01  /* (to 0x026C state 292) */,
+                       0x08, /* fail */
+/* pos 00e4:  62 */    0xF2 /* 'r' -> */,
+/* pos 00e5:  63 */    0xE1 /* 'a' -> */,
+/* pos 00e6:  64 */    0xE6 /* 'f' -> */,
+/* pos 00e7:  65 */    0xF4 /* 't' -> */,
+/* pos 00e8:  66 */    0xBA /* ':' -> */,
+/* pos 00e9:  67 */    0x00, 0x07                  /* - terminal marker  7 - */,
+/* pos 00eb:  68 */    0x8A /* '.' -> */,
+/* pos 00ec:  69 */    0x00, 0x08                  /* - terminal marker  8 - */,
+/* pos 00ee:  70 */    0xF8 /* 'x' -> */,
+/* pos 00ef:  71 */    0xF4 /* 't' -> */,
+/* pos 00f0:  72 */    0xE5 /* 'e' -> */,
+/* pos 00f1:  73 */    0xEE /* 'n' -> */,
+/* pos 00f2:  74 */    0xF3 /* 's' -> */,
+/* pos 00f3:  75 */    0xE9 /* 'i' -> */,
+/* pos 00f4:  76 */    0xEF /* 'o' -> */,
+/* pos 00f5:  77 */    0xEE /* 'n' -> */,
+/* pos 00f6:  78 */    0xF3 /* 's' -> */,
+/* pos 00f7:  79 */    0xBA /* ':' -> */,
+/* pos 00f8:  80 */    0x00, 0x09                  /* - terminal marker  9 - */,
+/* pos 00fa:  81 */    0xE5 /* 'e' -> */,
+/* pos 00fb:  82 */    0xF9 /* 'y' -> */,
+/* pos 00fc:  83 */    0x31 /* '1' */, 0x0A, 0x00  /* (to 0x0106 state  84) */,
+                       0x32 /* '2' */, 0x0A, 0x00  /* (to 0x0109 state  86) */,
+                       0x3A /* ':' */, 0x5F, 0x01  /* (to 0x0261 state 283) */,
+                       0x08, /* fail */
+/* pos 0106:  84 */    0xBA /* ':' -> */,
+/* pos 0107:  85 */    0x00, 0x0A                  /* - terminal marker 10 - */,
+/* pos 0109:  86 */    0xBA /* ':' -> */,
+/* pos 010a:  87 */    0x00, 0x0B                  /* - terminal marker 11 - */,
+/* pos 010c:  88 */    0xF2 /* 'r' -> */,
+/* pos 010d:  89 */    0xEF /* 'o' -> */,
+/* pos 010e:  90 */    0xF4 /* 't' -> */,
+/* pos 010f:  91 */    0xEF /* 'o' -> */,
+/* pos 0110:  92 */    0xE3 /* 'c' -> */,
+/* pos 0111:  93 */    0xEF /* 'o' -> */,
+/* pos 0112:  94 */    0xEC /* 'l' -> */,
+/* pos 0113:  95 */    0xBA /* ':' -> */,
+/* pos 0114:  96 */    0x00, 0x0C                  /* - terminal marker 12 - */,
+/* pos 0116:  97 */    0xE3 /* 'c' -> */,
+/* pos 0117:  98 */    0xE3 /* 'c' -> */,
+/* pos 0118:  99 */    0xE5 /* 'e' -> */,
+/* pos 0119: 100 */    0xF0 /* 'p' -> */,
+/* pos 011a: 101 */    0xF4 /* 't' -> */,
+/* pos 011b: 102 */    0xBA /* ':' -> */,
+/* pos 011c: 103 */    0x00, 0x0D                  /* - terminal marker 13 - */,
+/* pos 011e: 104 */    0xEF /* 'o' -> */,
+/* pos 011f: 105 */    0xEE /* 'n' -> */,
+/* pos 0120: 106 */    0xE3 /* 'c' -> */,
+/* pos 0121: 107 */    0xE5 /* 'e' -> */,
+/* pos 0122: 108 */    0xBA /* ':' -> */,
+/* pos 0123: 109 */    0x00, 0x0E                  /* - terminal marker 14 - */,
+/* pos 0125: 110 */    0xF4 /* 't' -> */,
+/* pos 0126: 111 */    0xF0 /* 'p' -> */,
+/* pos 0127: 112 */    0x2F /* '/' */, 0x07, 0x00  /* (to 0x012E state 113) */,
+                       0x32 /* '2' */, 0x10, 0x00  /* (to 0x013A state 118) */,
+                       0x08, /* fail */
+/* pos 012e: 113 */    0xB1 /* '1' -> */,
+/* pos 012f: 114 */    0xAE /* '.' -> */,
+/* pos 0130: 115 */    0x31 /* '1' */, 0x07, 0x00  /* (to 0x0137 state 116) */,
+                       0x30 /* '0' */, 0x15, 0x03  /* (to 0x0448 state 660) */,
+                       0x08, /* fail */
+/* pos 0137: 116 */    0xA0 /* ' ' -> */,
+/* pos 0138: 117 */    0x00, 0x0F                  /* - terminal marker 15 - */,
+/* pos 013a: 118 */    0xAD /* '-' -> */,
+/* pos 013b: 119 */    0xF3 /* 's' -> */,
+/* pos 013c: 120 */    0xE5 /* 'e' -> */,
+/* pos 013d: 121 */    0xF4 /* 't' -> */,
+/* pos 013e: 122 */    0xF4 /* 't' -> */,
+/* pos 013f: 123 */    0xE9 /* 'i' -> */,
+/* pos 0140: 124 */    0xEE /* 'n' -> */,
+/* pos 0141: 125 */    0xE7 /* 'g' -> */,
+/* pos 0142: 126 */    0xF3 /* 's' -> */,
+/* pos 0143: 127 */    0xBA /* ':' -> */,
+/* pos 0144: 128 */    0x00, 0x10                  /* - terminal marker 16 - */,
+/* pos 0146: 129 */    0x63 /* 'c' */, 0x0D, 0x00  /* (to 0x0153 state 130) */,
+                       0x75 /* 'u' */, 0xAC, 0x00  /* (to 0x01F5 state 230) */,
+                       0x67 /* 'g' */, 0x7D, 0x01  /* (to 0x02C9 state 358) */,
+                       0x6C /* 'l' */, 0x7E, 0x01  /* (to 0x02CD state 361) */,
+                       0x08, /* fail */
+/* pos 0153: 130 */    0xE3 /* 'c' -> */,
+/* pos 0154: 131 */    0xE5 /* 'e' -> */,
+/* pos 0155: 132 */    0x70 /* 'p' */, 0x07, 0x00  /* (to 0x015C state 133) */,
+                       0x73 /* 's' */, 0x0E, 0x00  /* (to 0x0166 state 136) */,
+                       0x08, /* fail */
+/* pos 015c: 133 */    0xF4 /* 't' -> */,
+/* pos 015d: 134 */    0x3A /* ':' */, 0x07, 0x00  /* (to 0x0164 state 135) */,
+                       0x2D /* '-' */, 0x59, 0x00  /* (to 0x01B9 state 192) */,
+                       0x08, /* fail */
+/* pos 0164: 135 */    0x00, 0x11                  /* - terminal marker 17 - */,
+/* pos 0166: 136 */    0xF3 /* 's' -> */,
+/* pos 0167: 137 */    0xAD /* '-' -> */,
+/* pos 0168: 138 */    0xE3 /* 'c' -> */,
+/* pos 0169: 139 */    0xEF /* 'o' -> */,
+/* pos 016a: 140 */    0xEE /* 'n' -> */,
+/* pos 016b: 141 */    0xF4 /* 't' -> */,
+/* pos 016c: 142 */    0xF2 /* 'r' -> */,
+/* pos 016d: 143 */    0xEF /* 'o' -> */,
+/* pos 016e: 144 */    0xEC /* 'l' -> */,
+/* pos 016f: 145 */    0xAD /* '-' -> */,
+/* pos 0170: 146 */    0x72 /* 'r' */, 0x07, 0x00  /* (to 0x0177 state 147) */,
+                       0x61 /* 'a' */, 0x48, 0x01  /* (to 0x02BB state 345) */,
+                       0x08, /* fail */
+/* pos 0177: 147 */    0xE5 /* 'e' -> */,
+/* pos 0178: 148 */    0xF1 /* 'q' -> */,
+/* pos 0179: 149 */    0xF5 /* 'u' -> */,
+/* pos 017a: 150 */    0xE5 /* 'e' -> */,
+/* pos 017b: 151 */    0xF3 /* 's' -> */,
+/* pos 017c: 152 */    0xF4 /* 't' -> */,
+/* pos 017d: 153 */    0xAD /* '-' -> */,
+/* pos 017e: 154 */    0xE8 /* 'h' -> */,
+/* pos 017f: 155 */    0xE5 /* 'e' -> */,
+/* pos 0180: 156 */    0xE1 /* 'a' -> */,
+/* pos 0181: 157 */    0xE4 /* 'd' -> */,
+/* pos 0182: 158 */    0xE5 /* 'e' -> */,
+/* pos 0183: 159 */    0xF2 /* 'r' -> */,
+/* pos 0184: 160 */    0xF3 /* 's' -> */,
+/* pos 0185: 161 */    0xBA /* ':' -> */,
+/* pos 0186: 162 */    0x00, 0x12                  /* - terminal marker 18 - */,
+/* pos 0188: 163 */    0xE6 /* 'f' -> */,
+/* pos 0189: 164 */    0xAD /* '-' -> */,
+/* pos 018a: 165 */    0x6D /* 'm' */, 0x0D, 0x00  /* (to 0x0197 state 166) */,
+                       0x6E /* 'n' */, 0x20, 0x00  /* (to 0x01AD state 181) */,
+                       0x72 /* 'r' */, 0x9E, 0x01  /* (to 0x032E state 435) */,
+                       0x75 /* 'u' */, 0xA2, 0x01  /* (to 0x0335 state 441) */,
+                       0x08, /* fail */
+/* pos 0197: 166 */    0x6F /* 'o' */, 0x07, 0x00  /* (to 0x019E state 167) */,
+                       0x61 /* 'a' */, 0x8E, 0x01  /* (to 0x0328 state 430) */,
+                       0x08, /* fail */
+/* pos 019e: 167 */    0xE4 /* 'd' -> */,
+/* pos 019f: 168 */    0xE9 /* 'i' -> */,
+/* pos 01a0: 169 */    0xE6 /* 'f' -> */,
+/* pos 01a1: 170 */    0xE9 /* 'i' -> */,
+/* pos 01a2: 171 */    0xE5 /* 'e' -> */,
+/* pos 01a3: 172 */    0xE4 /* 'd' -> */,
+/* pos 01a4: 173 */    0xAD /* '-' -> */,
+/* pos 01a5: 174 */    0xF3 /* 's' -> */,
+/* pos 01a6: 175 */    0xE9 /* 'i' -> */,
+/* pos 01a7: 176 */    0xEE /* 'n' -> */,
+/* pos 01a8: 177 */    0xE3 /* 'c' -> */,
+/* pos 01a9: 178 */    0xE5 /* 'e' -> */,
+/* pos 01aa: 179 */    0xBA /* ':' -> */,
+/* pos 01ab: 180 */    0x00, 0x13                  /* - terminal marker 19 - */,
+/* pos 01ad: 181 */    0xEF /* 'o' -> */,
+/* pos 01ae: 182 */    0xEE /* 'n' -> */,
+/* pos 01af: 183 */    0xE5 /* 'e' -> */,
+/* pos 01b0: 184 */    0xAD /* '-' -> */,
+/* pos 01b1: 185 */    0xED /* 'm' -> */,
+/* pos 01b2: 186 */    0xE1 /* 'a' -> */,
+/* pos 01b3: 187 */    0xF4 /* 't' -> */,
+/* pos 01b4: 188 */    0xE3 /* 'c' -> */,
+/* pos 01b5: 189 */    0xE8 /* 'h' -> */,
+/* pos 01b6: 190 */    0xBA /* ':' -> */,
+/* pos 01b7: 191 */    0x00, 0x14                  /* - terminal marker 20 - */,
+/* pos 01b9: 192 */    0x65 /* 'e' */, 0x0D, 0x00  /* (to 0x01C6 state 193) */,
+                       0x6C /* 'l' */, 0x14, 0x00  /* (to 0x01D0 state 202) */,
+                       0x63 /* 'c' */, 0xEB, 0x00  /* (to 0x02AA state 330) */,
+                       0x72 /* 'r' */, 0xF1, 0x00  /* (to 0x02B3 state 338) */,
+                       0x08, /* fail */
+/* pos 01c6: 193 */    0xEE /* 'n' -> */,
+/* pos 01c7: 194 */    0xE3 /* 'c' -> */,
+/* pos 01c8: 195 */    0xEF /* 'o' -> */,
+/* pos 01c9: 196 */    0xE4 /* 'd' -> */,
+/* pos 01ca: 197 */    0xE9 /* 'i' -> */,
+/* pos 01cb: 198 */    0xEE /* 'n' -> */,
+/* pos 01cc: 199 */    0xE7 /* 'g' -> */,
+/* pos 01cd: 200 */    0xBA /* ':' -> */,
+/* pos 01ce: 201 */    0x00, 0x15                  /* - terminal marker 21 - */,
+/* pos 01d0: 202 */    0xE1 /* 'a' -> */,
+/* pos 01d1: 203 */    0xEE /* 'n' -> */,
+/* pos 01d2: 204 */    0xE7 /* 'g' -> */,
+/* pos 01d3: 205 */    0xF5 /* 'u' -> */,
+/* pos 01d4: 206 */    0xE1 /* 'a' -> */,
+/* pos 01d5: 207 */    0xE7 /* 'g' -> */,
+/* pos 01d6: 208 */    0xE5 /* 'e' -> */,
+/* pos 01d7: 209 */    0xBA /* ':' -> */,
+/* pos 01d8: 210 */    0x00, 0x16                  /* - terminal marker 22 - */,
+/* pos 01da: 211 */    0x61 /* 'a' */, 0x07, 0x00  /* (to 0x01E1 state 212) */,
+                       0x6F /* 'o' */, 0x9E, 0x01  /* (to 0x037B state 497) */,
+                       0x08, /* fail */
+/* pos 01e1: 212 */    0xE7 /* 'g' -> */,
+/* pos 01e2: 213 */    0xED /* 'm' -> */,
+/* pos 01e3: 214 */    0xE1 /* 'a' -> */,
+/* pos 01e4: 215 */    0xBA /* ':' -> */,
+/* pos 01e5: 216 */    0x00, 0x17                  /* - terminal marker 23 - */,
+/* pos 01e7: 217 */    0xE3 /* 'c' -> */,
+/* pos 01e8: 218 */    0xE8 /* 'h' -> */,
+/* pos 01e9: 219 */    0xE5 /* 'e' -> */,
+/* pos 01ea: 220 */    0xAD /* '-' -> */,
+/* pos 01eb: 221 */    0xE3 /* 'c' -> */,
+/* pos 01ec: 222 */    0xEF /* 'o' -> */,
+/* pos 01ed: 223 */    0xEE /* 'n' -> */,
+/* pos 01ee: 224 */    0xF4 /* 't' -> */,
+/* pos 01ef: 225 */    0xF2 /* 'r' -> */,
+/* pos 01f0: 226 */    0xEF /* 'o' -> */,
+/* pos 01f1: 227 */    0xEC /* 'l' -> */,
+/* pos 01f2: 228 */    0xBA /* ':' -> */,
+/* pos 01f3: 229 */    0x00, 0x18                  /* - terminal marker 24 - */,
+/* pos 01f5: 230 */    0xF4 /* 't' -> */,
+/* pos 01f6: 231 */    0xE8 /* 'h' -> */,
+/* pos 01f7: 232 */    0xEF /* 'o' -> */,
+/* pos 01f8: 233 */    0xF2 /* 'r' -> */,
+/* pos 01f9: 234 */    0xE9 /* 'i' -> */,
+/* pos 01fa: 235 */    0xFA /* 'z' -> */,
+/* pos 01fb: 236 */    0xE1 /* 'a' -> */,
+/* pos 01fc: 237 */    0xF4 /* 't' -> */,
+/* pos 01fd: 238 */    0xE9 /* 'i' -> */,
+/* pos 01fe: 239 */    0xEF /* 'o' -> */,
+/* pos 01ff: 240 */    0xEE /* 'n' -> */,
+/* pos 0200: 241 */    0xBA /* ':' -> */,
+/* pos 0201: 242 */    0x00, 0x19                  /* - terminal marker 25 - */,
+/* pos 0203: 243 */    0xEB /* 'k' -> */,
+/* pos 0204: 244 */    0xE9 /* 'i' -> */,
+/* pos 0205: 245 */    0xE5 /* 'e' -> */,
+/* pos 0206: 246 */    0xBA /* ':' -> */,
+/* pos 0207: 247 */    0x00, 0x1A                  /* - terminal marker 26 - */,
+/* pos 0209: 248 */    0xE5 /* 'e' -> */,
+/* pos 020a: 249 */    0xEE /* 'n' -> */,
+/* pos 020b: 250 */    0xF4 /* 't' -> */,
+/* pos 020c: 251 */    0xAD /* '-' -> */,
+/* pos 020d: 252 */    0x6C /* 'l' */, 0x10, 0x00  /* (to 0x021D state 253) */,
+                       0x74 /* 't' */, 0x1E, 0x00  /* (to 0x022E state 260) */,
+                       0x64 /* 'd' */, 0xC0, 0x00  /* (to 0x02D3 state 366) */,
+                       0x65 /* 'e' */, 0xCA, 0x00  /* (to 0x02E0 state 378) */,
+                       0x72 /* 'r' */, 0xE3, 0x00  /* (to 0x02FC state 403) */,
+                       0x08, /* fail */
+/* pos 021d: 253 */    0x65 /* 'e' */, 0x0A, 0x00  /* (to 0x0227 state 254) */,
+                       0x61 /* 'a' */, 0xCA, 0x00  /* (to 0x02EA state 387) */,
+                       0x6F /* 'o' */, 0xD0, 0x00  /* (to 0x02F3 state 395) */,
+                       0x08, /* fail */
+/* pos 0227: 254 */    0xEE /* 'n' -> */,
+/* pos 0228: 255 */    0xE7 /* 'g' -> */,
+/* pos 0229: 256 */    0xF4 /* 't' -> */,
+/* pos 022a: 257 */    0xE8 /* 'h' -> */,
+/* pos 022b: 258 */    0xBA /* ':' -> */,
+/* pos 022c: 259 */    0x00, 0x1B                  /* - terminal marker 27 - */,
+/* pos 022e: 260 */    0xF9 /* 'y' -> */,
+/* pos 022f: 261 */    0xF0 /* 'p' -> */,
+/* pos 0230: 262 */    0xE5 /* 'e' -> */,
+/* pos 0231: 263 */    0xBA /* ':' -> */,
+/* pos 0232: 264 */    0x00, 0x1C                  /* - terminal marker 28 - */,
+/* pos 0234: 265 */    0x61 /* 'a' */, 0x07, 0x00  /* (to 0x023B state 266) */,
+                       0x65 /* 'e' */, 0xF0, 0x01  /* (to 0x0427 state 637) */,
+                       0x08, /* fail */
+/* pos 023b: 266 */    0xF4 /* 't' -> */,
+/* pos 023c: 267 */    0xE5 /* 'e' -> */,
+/* pos 023d: 268 */    0xBA /* ':' -> */,
+/* pos 023e: 269 */    0x00, 0x1D                  /* - terminal marker 29 - */,
+/* pos 0240: 270 */    0x61 /* 'a' */, 0x07, 0x00  /* (to 0x0247 state 271) */,
+                       0x65 /* 'e' */, 0x0A, 0x00  /* (to 0x024D state 276) */,
+                       0x08, /* fail */
+/* pos 0247: 271 */    0xEE /* 'n' -> */,
+/* pos 0248: 272 */    0xE7 /* 'g' -> */,
+/* pos 0249: 273 */    0xE5 /* 'e' -> */,
+/* pos 024a: 274 */    0xBA /* ':' -> */,
+/* pos 024b: 275 */    0x00, 0x1E                  /* - terminal marker 30 - */,
+/* pos 024d: 276 */    0x66 /* 'f' */, 0x07, 0x00  /* (to 0x0254 state 277) */,
+                       0x74 /* 't' */, 0x5A, 0x01  /* (to 0x03AA state 529) */,
+                       0x08, /* fail */
+/* pos 0254: 277 */    0x65 /* 'e' */, 0x07, 0x00  /* (to 0x025B state 278) */,
+                       0x72 /* 'r' */, 0x4D, 0x01  /* (to 0x03A4 state 524) */,
+                       0x08, /* fail */
+/* pos 025b: 278 */    0xF2 /* 'r' -> */,
+/* pos 025c: 279 */    0xE5 /* 'e' -> */,
+/* pos 025d: 280 */    0xF2 /* 'r' -> */,
+/* pos 025e: 281 */    0xBA /* ':' -> */,
+/* pos 025f: 282 */    0x00, 0x1F                  /* - terminal marker 31 - */,
+/* pos 0261: 283 */    0x00, 0x20                  /* - terminal marker 32 - */,
+/* pos 0263: 284 */    0xE5 /* 'e' -> */,
+/* pos 0264: 285 */    0xF2 /* 'r' -> */,
+/* pos 0265: 286 */    0xF3 /* 's' -> */,
+/* pos 0266: 287 */    0xE9 /* 'i' -> */,
+/* pos 0267: 288 */    0xEF /* 'o' -> */,
+/* pos 0268: 289 */    0xEE /* 'n' -> */,
+/* pos 0269: 290 */    0xBA /* ':' -> */,
+/* pos 026a: 291 */    0x00, 0x21                  /* - terminal marker 33 - */,
+/* pos 026c: 292 */    0xF2 /* 'r' -> */,
+/* pos 026d: 293 */    0xE9 /* 'i' -> */,
+/* pos 026e: 294 */    0xE7 /* 'g' -> */,
+/* pos 026f: 295 */    0xE9 /* 'i' -> */,
+/* pos 0270: 296 */    0xEE /* 'n' -> */,
+/* pos 0271: 297 */    0xBA /* ':' -> */,
+/* pos 0272: 298 */    0x00, 0x22                  /* - terminal marker 34 - */,
+/* pos 0274: 299 */    0x61 /* 'a' */, 0x0D, 0x00  /* (to 0x0281 state 300) */,
+                       0x6D /* 'm' */, 0x14, 0x00  /* (to 0x028B state 309) */,
+                       0x70 /* 'p' */, 0x18, 0x00  /* (to 0x0292 state 315) */,
+                       0x73 /* 's' */, 0x1A, 0x00  /* (to 0x0297 state 319) */,
+                       0x08, /* fail */
+/* pos 0281: 300 */    0xF5 /* 'u' -> */,
+/* pos 0282: 301 */    0xF4 /* 't' -> */,
+/* pos 0283: 302 */    0xE8 /* 'h' -> */,
+/* pos 0284: 303 */    0xEF /* 'o' -> */,
+/* pos 0285: 304 */    0xF2 /* 'r' -> */,
+/* pos 0286: 305 */    0xE9 /* 'i' -> */,
+/* pos 0287: 306 */    0xF4 /* 't' -> */,
+/* pos 0288: 307 */    0xF9 /* 'y' -> */,
+/* pos 0289: 308 */    0x00, 0x23                  /* - terminal marker 35 - */,
+/* pos 028b: 309 */    0xE5 /* 'e' -> */,
+/* pos 028c: 310 */    0xF4 /* 't' -> */,
+/* pos 028d: 311 */    0xE8 /* 'h' -> */,
+/* pos 028e: 312 */    0xEF /* 'o' -> */,
+/* pos 028f: 313 */    0xE4 /* 'd' -> */,
+/* pos 0290: 314 */    0x00, 0x24                  /* - terminal marker 36 - */,
+/* pos 0292: 315 */    0xE1 /* 'a' -> */,
+/* pos 0293: 316 */    0xF4 /* 't' -> */,
+/* pos 0294: 317 */    0xE8 /* 'h' -> */,
+/* pos 0295: 318 */    0x00, 0x25                  /* - terminal marker 37 - */,
+/* pos 0297: 319 */    0x63 /* 'c' */, 0x07, 0x00  /* (to 0x029E state 320) */,
+                       0x74 /* 't' */, 0x0A, 0x00  /* (to 0x02A4 state 325) */,
+                       0x08, /* fail */
+/* pos 029e: 320 */    0xE8 /* 'h' -> */,
+/* pos 029f: 321 */    0xE5 /* 'e' -> */,
+/* pos 02a0: 322 */    0xED /* 'm' -> */,
+/* pos 02a1: 323 */    0xE5 /* 'e' -> */,
+/* pos 02a2: 324 */    0x00, 0x26                  /* - terminal marker 38 - */,
+/* pos 02a4: 325 */    0xE1 /* 'a' -> */,
+/* pos 02a5: 326 */    0xF4 /* 't' -> */,
+/* pos 02a6: 327 */    0xF5 /* 'u' -> */,
+/* pos 02a7: 328 */    0xF3 /* 's' -> */,
+/* pos 02a8: 329 */    0x00, 0x27                  /* - terminal marker 39 - */,
+/* pos 02aa: 330 */    0xE8 /* 'h' -> */,
+/* pos 02ab: 331 */    0xE1 /* 'a' -> */,
+/* pos 02ac: 332 */    0xF2 /* 'r' -> */,
+/* pos 02ad: 333 */    0xF3 /* 's' -> */,
+/* pos 02ae: 334 */    0xE5 /* 'e' -> */,
+/* pos 02af: 335 */    0xF4 /* 't' -> */,
+/* pos 02b0: 336 */    0xBA /* ':' -> */,
+/* pos 02b1: 337 */    0x00, 0x28                  /* - terminal marker 40 - */,
+/* pos 02b3: 338 */    0xE1 /* 'a' -> */,
+/* pos 02b4: 339 */    0xEE /* 'n' -> */,
+/* pos 02b5: 340 */    0xE7 /* 'g' -> */,
+/* pos 02b6: 341 */    0xE5 /* 'e' -> */,
+/* pos 02b7: 342 */    0xF3 /* 's' -> */,
+/* pos 02b8: 343 */    0xBA /* ':' -> */,
+/* pos 02b9: 344 */    0x00, 0x29                  /* - terminal marker 41 - */,
+/* pos 02bb: 345 */    0xEC /* 'l' -> */,
+/* pos 02bc: 346 */    0xEC /* 'l' -> */,
+/* pos 02bd: 347 */    0xEF /* 'o' -> */,
+/* pos 02be: 348 */    0xF7 /* 'w' -> */,
+/* pos 02bf: 349 */    0xAD /* '-' -> */,
+/* pos 02c0: 350 */    0xEF /* 'o' -> */,
+/* pos 02c1: 351 */    0xF2 /* 'r' -> */,
+/* pos 02c2: 352 */    0xE9 /* 'i' -> */,
+/* pos 02c3: 353 */    0xE7 /* 'g' -> */,
+/* pos 02c4: 354 */    0xE9 /* 'i' -> */,
+/* pos 02c5: 355 */    0xEE /* 'n' -> */,
+/* pos 02c6: 356 */    0xBA /* ':' -> */,
+/* pos 02c7: 357 */    0x00, 0x2A                  /* - terminal marker 42 - */,
+/* pos 02c9: 358 */    0xE5 /* 'e' -> */,
+/* pos 02ca: 359 */    0xBA /* ':' -> */,
+/* pos 02cb: 360 */    0x00, 0x2B                  /* - terminal marker 43 - */,
+/* pos 02cd: 361 */    0xEC /* 'l' -> */,
+/* pos 02ce: 362 */    0xEF /* 'o' -> */,
+/* pos 02cf: 363 */    0xF7 /* 'w' -> */,
+/* pos 02d0: 364 */    0xBA /* ':' -> */,
+/* pos 02d1: 365 */    0x00, 0x2C                  /* - terminal marker 44 - */,
+/* pos 02d3: 366 */    0xE9 /* 'i' -> */,
+/* pos 02d4: 367 */    0xF3 /* 's' -> */,
+/* pos 02d5: 368 */    0xF0 /* 'p' -> */,
+/* pos 02d6: 369 */    0xEF /* 'o' -> */,
+/* pos 02d7: 370 */    0xF3 /* 's' -> */,
+/* pos 02d8: 371 */    0xE9 /* 'i' -> */,
+/* pos 02d9: 372 */    0xF4 /* 't' -> */,
+/* pos 02da: 373 */    0xE9 /* 'i' -> */,
+/* pos 02db: 374 */    0xEF /* 'o' -> */,
+/* pos 02dc: 375 */    0xEE /* 'n' -> */,
+/* pos 02dd: 376 */    0xBA /* ':' -> */,
+/* pos 02de: 377 */    0x00, 0x2D                  /* - terminal marker 45 - */,
+/* pos 02e0: 378 */    0xEE /* 'n' -> */,
+/* pos 02e1: 379 */    0xE3 /* 'c' -> */,
+/* pos 02e2: 380 */    0xEF /* 'o' -> */,
+/* pos 02e3: 381 */    0xE4 /* 'd' -> */,
+/* pos 02e4: 382 */    0xE9 /* 'i' -> */,
+/* pos 02e5: 383 */    0xEE /* 'n' -> */,
+/* pos 02e6: 384 */    0xE7 /* 'g' -> */,
+/* pos 02e7: 385 */    0xBA /* ':' -> */,
+/* pos 02e8: 386 */    0x00, 0x2E                  /* - terminal marker 46 - */,
+/* pos 02ea: 387 */    0xEE /* 'n' -> */,
+/* pos 02eb: 388 */    0xE7 /* 'g' -> */,
+/* pos 02ec: 389 */    0xF5 /* 'u' -> */,
+/* pos 02ed: 390 */    0xE1 /* 'a' -> */,
+/* pos 02ee: 391 */    0xE7 /* 'g' -> */,
+/* pos 02ef: 392 */    0xE5 /* 'e' -> */,
+/* pos 02f0: 393 */    0xBA /* ':' -> */,
+/* pos 02f1: 394 */    0x00, 0x2F                  /* - terminal marker 47 - */,
+/* pos 02f3: 395 */    0xE3 /* 'c' -> */,
+/* pos 02f4: 396 */    0xE1 /* 'a' -> */,
+/* pos 02f5: 397 */    0xF4 /* 't' -> */,
+/* pos 02f6: 398 */    0xE9 /* 'i' -> */,
+/* pos 02f7: 399 */    0xEF /* 'o' -> */,
+/* pos 02f8: 400 */    0xEE /* 'n' -> */,
+/* pos 02f9: 401 */    0xBA /* ':' -> */,
+/* pos 02fa: 402 */    0x00, 0x30                  /* - terminal marker 48 - */,
+/* pos 02fc: 403 */    0xE1 /* 'a' -> */,
+/* pos 02fd: 404 */    0xEE /* 'n' -> */,
+/* pos 02fe: 405 */    0xE7 /* 'g' -> */,
+/* pos 02ff: 406 */    0xE5 /* 'e' -> */,
+/* pos 0300: 407 */    0xBA /* ':' -> */,
+/* pos 0301: 408 */    0x00, 0x31                  /* - terminal marker 49 - */,
+/* pos 0303: 409 */    0x74 /* 't' */, 0x07, 0x00  /* (to 0x030A state 410) */,
+                       0x78 /* 'x' */, 0x09, 0x00  /* (to 0x030F state 414) */,
+                       0x08, /* fail */
+/* pos 030a: 410 */    0xE1 /* 'a' -> */,
+/* pos 030b: 411 */    0xE7 /* 'g' -> */,
+/* pos 030c: 412 */    0xBA /* ':' -> */,
+/* pos 030d: 413 */    0x00, 0x32                  /* - terminal marker 50 - */,
+/* pos 030f: 414 */    0xF0 /* 'p' -> */,
+/* pos 0310: 415 */    0x65 /* 'e' */, 0x07, 0x00  /* (to 0x0317 state 416) */,
+                       0x69 /* 'i' */, 0x09, 0x00  /* (to 0x031C state 420) */,
+                       0x08, /* fail */
+/* pos 0317: 416 */    0xE3 /* 'c' -> */,
+/* pos 0318: 417 */    0xF4 /* 't' -> */,
+/* pos 0319: 418 */    0xBA /* ':' -> */,
+/* pos 031a: 419 */    0x00, 0x33                  /* - terminal marker 51 - */,
+/* pos 031c: 420 */    0xF2 /* 'r' -> */,
+/* pos 031d: 421 */    0xE5 /* 'e' -> */,
+/* pos 031e: 422 */    0xF3 /* 's' -> */,
+/* pos 031f: 423 */    0xBA /* ':' -> */,
+/* pos 0320: 424 */    0x00, 0x34                  /* - terminal marker 52 - */,
+/* pos 0322: 425 */    0xF2 /* 'r' -> */,
+/* pos 0323: 426 */    0xEF /* 'o' -> */,
+/* pos 0324: 427 */    0xED /* 'm' -> */,
+/* pos 0325: 428 */    0xBA /* ':' -> */,
+/* pos 0326: 429 */    0x00, 0x35                  /* - terminal marker 53 - */,
+/* pos 0328: 430 */    0xF4 /* 't' -> */,
+/* pos 0329: 431 */    0xE3 /* 'c' -> */,
+/* pos 032a: 432 */    0xE8 /* 'h' -> */,
+/* pos 032b: 433 */    0xBA /* ':' -> */,
+/* pos 032c: 434 */    0x00, 0x36                  /* - terminal marker 54 - */,
+/* pos 032e: 435 */    0xE1 /* 'a' -> */,
+/* pos 032f: 436 */    0xEE /* 'n' -> */,
+/* pos 0330: 437 */    0xE7 /* 'g' -> */,
+/* pos 0331: 438 */    0xE5 /* 'e' -> */,
+/* pos 0332: 439 */    0xBA /* ':' -> */,
+/* pos 0333: 440 */    0x00, 0x37                  /* - terminal marker 55 - */,
+/* pos 0335: 441 */    0xEE /* 'n' -> */,
+/* pos 0336: 442 */    0xED /* 'm' -> */,
+/* pos 0337: 443 */    0xEF /* 'o' -> */,
+/* pos 0338: 444 */    0xE4 /* 'd' -> */,
+/* pos 0339: 445 */    0xE9 /* 'i' -> */,
+/* pos 033a: 446 */    0xE6 /* 'f' -> */,
+/* pos 033b: 447 */    0xE9 /* 'i' -> */,
+/* pos 033c: 448 */    0xE5 /* 'e' -> */,
+/* pos 033d: 449 */    0xE4 /* 'd' -> */,
+/* pos 033e: 450 */    0xAD /* '-' -> */,
+/* pos 033f: 451 */    0xF3 /* 's' -> */,
+/* pos 0340: 452 */    0xE9 /* 'i' -> */,
+/* pos 0341: 453 */    0xEE /* 'n' -> */,
+/* pos 0342: 454 */    0xE3 /* 'c' -> */,
+/* pos 0343: 455 */    0xE5 /* 'e' -> */,
+/* pos 0344: 456 */    0xBA /* ':' -> */,
+/* pos 0345: 457 */    0x00, 0x38                  /* - terminal marker 56 - */,
+/* pos 0347: 458 */    0x61 /* 'a' */, 0x0A, 0x00  /* (to 0x0351 state 459) */,
+                       0x69 /* 'i' */, 0x15, 0x00  /* (to 0x035F state 472) */,
+                       0x6F /* 'o' */, 0x17, 0x00  /* (to 0x0364 state 476) */,
+                       0x08, /* fail */
+/* pos 0351: 459 */    0xF3 /* 's' -> */,
+/* pos 0352: 460 */    0xF4 /* 't' -> */,
+/* pos 0353: 461 */    0xAD /* '-' -> */,
+/* pos 0354: 462 */    0xED /* 'm' -> */,
+/* pos 0355: 463 */    0xEF /* 'o' -> */,
+/* pos 0356: 464 */    0xE4 /* 'd' -> */,
+/* pos 0357: 465 */    0xE9 /* 'i' -> */,
+/* pos 0358: 466 */    0xE6 /* 'f' -> */,
+/* pos 0359: 467 */    0xE9 /* 'i' -> */,
+/* pos 035a: 468 */    0xE5 /* 'e' -> */,
+/* pos 035b: 469 */    0xE4 /* 'd' -> */,
+/* pos 035c: 470 */    0xBA /* ':' -> */,
+/* pos 035d: 471 */    0x00, 0x39                  /* - terminal marker 57 - */,
+/* pos 035f: 472 */    0xEE /* 'n' -> */,
+/* pos 0360: 473 */    0xEB /* 'k' -> */,
+/* pos 0361: 474 */    0xBA /* ':' -> */,
+/* pos 0362: 475 */    0x00, 0x3A                  /* - terminal marker 58 - */,
+/* pos 0364: 476 */    0xE3 /* 'c' -> */,
+/* pos 0365: 477 */    0xE1 /* 'a' -> */,
+/* pos 0366: 478 */    0xF4 /* 't' -> */,
+/* pos 0367: 479 */    0xE9 /* 'i' -> */,
+/* pos 0368: 480 */    0xEF /* 'o' -> */,
+/* pos 0369: 481 */    0xEE /* 'n' -> */,
+/* pos 036a: 482 */    0xBA /* ':' -> */,
+/* pos 036b: 483 */    0x00, 0x3B                  /* - terminal marker 59 - */,
+/* pos 036d: 484 */    0xE1 /* 'a' -> */,
+/* pos 036e: 485 */    0xF8 /* 'x' -> */,
+/* pos 036f: 486 */    0xAD /* '-' -> */,
+/* pos 0370: 487 */    0xE6 /* 'f' -> */,
+/* pos 0371: 488 */    0xEF /* 'o' -> */,
+/* pos 0372: 489 */    0xF2 /* 'r' -> */,
+/* pos 0373: 490 */    0xF7 /* 'w' -> */,
+/* pos 0374: 491 */    0xE1 /* 'a' -> */,
+/* pos 0375: 492 */    0xF2 /* 'r' -> */,
+/* pos 0376: 493 */    0xE4 /* 'd' -> */,
+/* pos 0377: 494 */    0xF3 /* 's' -> */,
+/* pos 0378: 495 */    0xBA /* ':' -> */,
+/* pos 0379: 496 */    0x00, 0x3C                  /* - terminal marker 60 - */,
+/* pos 037b: 497 */    0xF8 /* 'x' -> */,
+/* pos 037c: 498 */    0xF9 /* 'y' -> */,
+/* pos 037d: 499 */    0x2D /* '-' */, 0x07, 0x00  /* (to 0x0384 state 500) */,
+                       0x20 /* ' ' */, 0xB5, 0x00  /* (to 0x0435 state 649) */,
+                       0x08, /* fail */
+/* pos 0384: 500 */    0xE1 /* 'a' -> */,
+/* pos 0385: 501 */    0xF5 /* 'u' -> */,
+/* pos 0386: 502 */    0xF4 /* 't' -> */,
+/* pos 0387: 503 */    0xE8 /* 'h' -> */,
+/* pos 0388: 504 */    0x65 /* 'e' */, 0x07, 0x00  /* (to 0x038F state 505) */,
+                       0x6F /* 'o' */, 0x0E, 0x00  /* (to 0x0399 state 514) */,
+                       0x08, /* fail */
+/* pos 038f: 505 */    0xEE /* 'n' -> */,
+/* pos 0390: 506 */    0xF4 /* 't' -> */,
+/* pos 0391: 507 */    0xE9 /* 'i' -> */,
+/* pos 0392: 508 */    0xE3 /* 'c' -> */,
+/* pos 0393: 509 */    0xE1 /* 'a' -> */,
+/* pos 0394: 510 */    0xF4 /* 't' -> */,
+/* pos 0395: 511 */    0xE5 /* 'e' -> */,
+/* pos 0396: 512 */    0xBA /* ':' -> */,
+/* pos 0397: 513 */    0x00, 0x3D                  /* - terminal marker 61 - */,
+/* pos 0399: 514 */    0xF2 /* 'r' -> */,
+/* pos 039a: 515 */    0xE9 /* 'i' -> */,
+/* pos 039b: 516 */    0xFA /* 'z' -> */,
+/* pos 039c: 517 */    0xE1 /* 'a' -> */,
+/* pos 039d: 518 */    0xF4 /* 't' -> */,
+/* pos 039e: 519 */    0xE9 /* 'i' -> */,
+/* pos 039f: 520 */    0xEF /* 'o' -> */,
+/* pos 03a0: 521 */    0xEE /* 'n' -> */,
+/* pos 03a1: 522 */    0xBA /* ':' -> */,
+/* pos 03a2: 523 */    0x00, 0x3E                  /* - terminal marker 62 - */,
+/* pos 03a4: 524 */    0xE5 /* 'e' -> */,
+/* pos 03a5: 525 */    0xF3 /* 's' -> */,
+/* pos 03a6: 526 */    0xE8 /* 'h' -> */,
+/* pos 03a7: 527 */    0xBA /* ':' -> */,
+/* pos 03a8: 528 */    0x00, 0x3F                  /* - terminal marker 63 - */,
+/* pos 03aa: 529 */    0xF2 /* 'r' -> */,
+/* pos 03ab: 530 */    0xF9 /* 'y' -> */,
+/* pos 03ac: 531 */    0xAD /* '-' -> */,
+/* pos 03ad: 532 */    0xE1 /* 'a' -> */,
+/* pos 03ae: 533 */    0xE6 /* 'f' -> */,
+/* pos 03af: 534 */    0xF4 /* 't' -> */,
+/* pos 03b0: 535 */    0xE5 /* 'e' -> */,
+/* pos 03b1: 536 */    0xF2 /* 'r' -> */,
+/* pos 03b2: 537 */    0xBA /* ':' -> */,
+/* pos 03b3: 538 */    0x00, 0x40                  /* - terminal marker 64 - */,
+/* pos 03b5: 539 */    0xF6 /* 'v' -> */,
+/* pos 03b6: 540 */    0xE5 /* 'e' -> */,
+/* pos 03b7: 541 */    0xF2 /* 'r' -> */,
+/* pos 03b8: 542 */    0xBA /* ':' -> */,
+/* pos 03b9: 543 */    0x00, 0x41                  /* - terminal marker 65 - */,
+/* pos 03bb: 544 */    0xAD /* '-' -> */,
+/* pos 03bc: 545 */    0xE3 /* 'c' -> */,
+/* pos 03bd: 546 */    0xEF /* 'o' -> */,
+/* pos 03be: 547 */    0xEF /* 'o' -> */,
+/* pos 03bf: 548 */    0xEB /* 'k' -> */,
+/* pos 03c0: 549 */    0xE9 /* 'i' -> */,
+/* pos 03c1: 550 */    0xE5 /* 'e' -> */,
+/* pos 03c2: 551 */    0xBA /* ':' -> */,
+/* pos 03c3: 552 */    0x00, 0x42                  /* - terminal marker 66 - */,
+/* pos 03c5: 553 */    0xF2 /* 'r' -> */,
+/* pos 03c6: 554 */    0xE9 /* 'i' -> */,
+/* pos 03c7: 555 */    0xE3 /* 'c' -> */,
+/* pos 03c8: 556 */    0xF4 /* 't' -> */,
+/* pos 03c9: 557 */    0xAD /* '-' -> */,
+/* pos 03ca: 558 */    0xF4 /* 't' -> */,
+/* pos 03cb: 559 */    0xF2 /* 'r' -> */,
+/* pos 03cc: 560 */    0xE1 /* 'a' -> */,
+/* pos 03cd: 561 */    0xEE /* 'n' -> */,
+/* pos 03ce: 562 */    0xF3 /* 's' -> */,
+/* pos 03cf: 563 */    0xF0 /* 'p' -> */,
+/* pos 03d0: 564 */    0xEF /* 'o' -> */,
+/* pos 03d1: 565 */    0xF2 /* 'r' -> */,
+/* pos 03d2: 566 */    0xF4 /* 't' -> */,
+/* pos 03d3: 567 */    0xAD /* '-' -> */,
+/* pos 03d4: 568 */    0xF3 /* 's' -> */,
+/* pos 03d5: 569 */    0xE5 /* 'e' -> */,
+/* pos 03d6: 570 */    0xE3 /* 'c' -> */,
+/* pos 03d7: 571 */    0xF5 /* 'u' -> */,
+/* pos 03d8: 572 */    0xF2 /* 'r' -> */,
+/* pos 03d9: 573 */    0xE9 /* 'i' -> */,
+/* pos 03da: 574 */    0xF4 /* 't' -> */,
+/* pos 03db: 575 */    0xF9 /* 'y' -> */,
+/* pos 03dc: 576 */    0xBA /* ':' -> */,
+/* pos 03dd: 577 */    0x00, 0x43                  /* - terminal marker 67 - */,
+/* pos 03df: 578 */    0xF2 /* 'r' -> */,
+/* pos 03e0: 579 */    0xE1 /* 'a' -> */,
+/* pos 03e1: 580 */    0xEE /* 'n' -> */,
+/* pos 03e2: 581 */    0xF3 /* 's' -> */,
+/* pos 03e3: 582 */    0xE6 /* 'f' -> */,
+/* pos 03e4: 583 */    0xE5 /* 'e' -> */,
+/* pos 03e5: 584 */    0xF2 /* 'r' -> */,
+/* pos 03e6: 585 */    0xAD /* '-' -> */,
+/* pos 03e7: 586 */    0xE5 /* 'e' -> */,
+/* pos 03e8: 587 */    0xEE /* 'n' -> */,
+/* pos 03e9: 588 */    0xE3 /* 'c' -> */,
+/* pos 03ea: 589 */    0xEF /* 'o' -> */,
+/* pos 03eb: 590 */    0xE4 /* 'd' -> */,
+/* pos 03ec: 591 */    0xE9 /* 'i' -> */,
+/* pos 03ed: 592 */    0xEE /* 'n' -> */,
+/* pos 03ee: 593 */    0xE7 /* 'g' -> */,
+/* pos 03ef: 594 */    0xBA /* ':' -> */,
+/* pos 03f0: 595 */    0x00, 0x44                  /* - terminal marker 68 - */,
+/* pos 03f2: 596 */    0xE5 /* 'e' -> */,
+/* pos 03f3: 597 */    0xF2 /* 'r' -> */,
+/* pos 03f4: 598 */    0xAD /* '-' -> */,
+/* pos 03f5: 599 */    0xE1 /* 'a' -> */,
+/* pos 03f6: 600 */    0xE7 /* 'g' -> */,
+/* pos 03f7: 601 */    0xE5 /* 'e' -> */,
+/* pos 03f8: 602 */    0xEE /* 'n' -> */,
+/* pos 03f9: 603 */    0xF4 /* 't' -> */,
+/* pos 03fa: 604 */    0xBA /* ':' -> */,
+/* pos 03fb: 605 */    0x00, 0x45                  /* - terminal marker 69 - */,
+/* pos 03fd: 606 */    0x61 /* 'a' */, 0x07, 0x00  /* (to 0x0404 state 607) */,
+                       0x69 /* 'i' */, 0x09, 0x00  /* (to 0x0409 state 611) */,
+                       0x08, /* fail */
+/* pos 0404: 607 */    0xF2 /* 'r' -> */,
+/* pos 0405: 608 */    0xF9 /* 'y' -> */,
+/* pos 0406: 609 */    0xBA /* ':' -> */,
+/* pos 0407: 610 */    0x00, 0x46                  /* - terminal marker 70 - */,
+/* pos 0409: 611 */    0xE1 /* 'a' -> */,
+/* pos 040a: 612 */    0xBA /* ':' -> */,
+/* pos 040b: 613 */    0x00, 0x47                  /* - terminal marker 71 - */,
+/* pos 040d: 614 */    0xF7 /* 'w' -> */,
+/* pos 040e: 615 */    0xF7 /* 'w' -> */,
+/* pos 040f: 616 */    0xAD /* '-' -> */,
+/* pos 0410: 617 */    0xE1 /* 'a' -> */,
+/* pos 0411: 618 */    0xF5 /* 'u' -> */,
+/* pos 0412: 619 */    0xF4 /* 't' -> */,
+/* pos 0413: 620 */    0xE8 /* 'h' -> */,
+/* pos 0414: 621 */    0xE5 /* 'e' -> */,
+/* pos 0415: 622 */    0xEE /* 'n' -> */,
+/* pos 0416: 623 */    0xF4 /* 't' -> */,
+/* pos 0417: 624 */    0xE9 /* 'i' -> */,
+/* pos 0418: 625 */    0xE3 /* 'c' -> */,
+/* pos 0419: 626 */    0xE1 /* 'a' -> */,
+/* pos 041a: 627 */    0xF4 /* 't' -> */,
+/* pos 041b: 628 */    0xE5 /* 'e' -> */,
+/* pos 041c: 629 */    0xBA /* ':' -> */,
+/* pos 041d: 630 */    0x00, 0x48                  /* - terminal marker 72 - */,
+/* pos 041f: 631 */    0xF4 /* 't' -> */,
+/* pos 0420: 632 */    0xE3 /* 'c' -> */,
+/* pos 0421: 633 */    0xE8 /* 'h' -> */,
+/* pos 0422: 634 */    0x00, 0x49                  /* - terminal marker 73 - */,
+/* pos 0424: 635 */    0xF4 /* 't' -> */,
+/* pos 0425: 636 */    0x00, 0x4A                  /* - terminal marker 74 - */,
+/* pos 0427: 637 */    0xEC /* 'l' -> */,
+/* pos 0428: 638 */    0xE5 /* 'e' -> */,
+/* pos 0429: 639 */    0xF4 /* 't' -> */,
+/* pos 042a: 640 */    0xE5 /* 'e' -> */,
+/* pos 042b: 641 */    0x00, 0x4B                  /* - terminal marker 75 - */,
+/* pos 042d: 642 */    0xE9 /* 'i' -> */,
+/* pos 042e: 643 */    0xAD /* '-' -> */,
+/* pos 042f: 644 */    0xE1 /* 'a' -> */,
+/* pos 0430: 645 */    0xF2 /* 'r' -> */,
+/* pos 0431: 646 */    0xE7 /* 'g' -> */,
+/* pos 0432: 647 */    0xF3 /* 's' -> */,
+/* pos 0433: 648 */    0x00, 0x4C                  /* - terminal marker 76 - */,
+/* pos 0435: 649 */    0x00, 0x4D                  /* - terminal marker 77 - */,
+/* pos 0437: 650 */    0xAD /* '-' -> */,
+/* pos 0438: 651 */    0x72 /* 'r' */, 0x07, 0x00  /* (to 0x043F state 652) */,
+                       0x66 /* 'f' */, 0x10, 0x00  /* (to 0x044B state 662) */,
+                       0x08, /* fail */
+/* pos 043f: 652 */    0xE5 /* 'e' -> */,
+/* pos 0440: 653 */    0xE1 /* 'a' -> */,
+/* pos 0441: 654 */    0xEC /* 'l' -> */,
+/* pos 0442: 655 */    0xAD /* '-' -> */,
+/* pos 0443: 656 */    0xE9 /* 'i' -> */,
+/* pos 0444: 657 */    0xF0 /* 'p' -> */,
+/* pos 0445: 658 */    0xBA /* ':' -> */,
+/* pos 0446: 659 */    0x00, 0x4E                  /* - terminal marker 78 - */,
+/* pos 0448: 660 */    0xA0 /* ' ' -> */,
+/* pos 0449: 661 */    0x00, 0x4F                  /* - terminal marker 79 - */,
+/* pos 044b: 662 */    0xEF /* 'o' -> */,
+/* pos 044c: 663 */    0xF2 /* 'r' -> */,
+/* pos 044d: 664 */    0xF7 /* 'w' -> */,
+/* pos 044e: 665 */    0xE1 /* 'a' -> */,
+/* pos 044f: 666 */    0xF2 /* 'r' -> */,
+/* pos 0450: 667 */    0xE4 /* 'd' -> */,
+/* pos 0451: 668 */    0xE5 /* 'e' -> */,
+/* pos 0452: 669 */    0xE4 /* 'd' -> */,
+/* pos 0453: 670 */    0xAD /* '-' -> */,
+/* pos 0454: 671 */    0xE6 /* 'f' -> */,
+/* pos 0455: 672 */    0xEF /* 'o' -> */,
+/* pos 0456: 673 */    0xF2 /* 'r' -> */,
+/* pos 0457: 674 */    0x00, 0x50                  /* - terminal marker 80 - */,
+/* pos 0459: 675 */    0x00, 0x51                  /* - terminal marker 81 - */,
+/* total size 1115 bytes */

+ 11 - 5
EVSE/GPL/libwebsockets-v2.1-stable/lib/libev.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/libev.c

@@ -97,7 +97,7 @@ lws_ev_initloop(struct lws_context *context, struct ev_loop *loop, int tsi)
 	while (vh) {
 		if (vh->lserv_wsi) {
 			vh->lserv_wsi->w_read.context = context;
-			ev_io_init(w_accept, lws_accept_cb, vh->lserv_wsi->sock,
+			ev_io_init(w_accept, lws_accept_cb, vh->lserv_wsi->desc.sockfd,
 				  EV_READ);
 		}
 		vh = vh->vhost_next;
@@ -160,19 +160,25 @@ lws_libev_destroyloop(struct lws_context *context, int tsi)
 }
 
 LWS_VISIBLE void
-lws_libev_accept(struct lws *new_wsi, int accept_fd)
+lws_libev_accept(struct lws *new_wsi, lws_sock_file_fd_type desc)
 {
 	struct lws_context *context = lws_get_context(new_wsi);
 	struct ev_io *r = &new_wsi->w_read.ev_watcher;
 	struct ev_io *w = &new_wsi->w_write.ev_watcher;
+	int fd;
 
 	if (!LWS_LIBEV_ENABLED(context))
 		return;
 
+	if (new_wsi->mode == LWSCM_RAW_FILEDESC)
+		fd = desc.filefd;
+	else
+		fd = desc.sockfd;
+
 	new_wsi->w_read.context = context;
 	new_wsi->w_write.context = context;
-	ev_io_init(r, lws_accept_cb, accept_fd, EV_READ);
-	ev_io_init(w, lws_accept_cb, accept_fd, EV_WRITE);
+	ev_io_init(r, lws_accept_cb, fd, EV_READ);
+	ev_io_init(w, lws_accept_cb, fd, EV_WRITE);
 }
 
 LWS_VISIBLE void
@@ -184,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)) &&

+ 153 - 68
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/libuv.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/libuv.c

@@ -40,18 +40,18 @@ 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?
 	 */
 	if (!lws_service_adjust_timeout(pt->context, 1, pt->tid)) {
 		/* -1 timeout means just do forced service */
-		lws_plat_service_tsi(pt->context, -1, pt->tid);
+		_lws_plat_service_tsi(pt->context, -1, pt->tid);
 		/* 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;
 	}
 
@@ -67,7 +67,7 @@ lws_io_cb(uv_poll_t *watcher, int status, int revents)
 	struct lws_io_watcher *lws_io = lws_container_of(watcher,
 					struct lws_io_watcher, uv_watcher);
 	struct lws *wsi = lws_container_of(lws_io, struct lws, w_read);
-	struct lws_context *context = lws_io->context;
+	struct lws_context *context = wsi->context;
 	struct lws_pollfd eventfd;
 
 #if defined(WIN32) || defined(_WIN32)
@@ -141,49 +141,93 @@ lws_uv_timeout_cb(uv_timer_t *timer
 	lws_service_fd_tsi(pt->context, NULL, pt->tid);
 }
 
-static const int sigs[] = { SIGINT, SIGTERM, SIGSEGV, SIGFPE };
+static const int sigs[] = { SIGINT, SIGTERM, SIGSEGV, SIGFPE, SIGHUP };
+
+int
+lws_uv_initvhost(struct lws_vhost* vh, struct lws* wsi)
+{
+	struct lws_context_per_thread *pt;
+	int n;
+
+	if (!LWS_LIBUV_ENABLED(vh->context))
+		return 0;
+	if (!wsi)
+		wsi = vh->lserv_wsi;
+	if (!wsi)
+		return 0;
+	if (wsi->w_read.context)
+		return 0;
+
+	pt = &vh->context->pt[(int)wsi->tsi];
+	if (!pt->io_loop_uv)
+		return 0;
+
+	wsi->w_read.context = vh->context;
+	n = uv_poll_init_socket(pt->io_loop_uv,
+				&wsi->w_read.uv_watcher, wsi->desc.sockfd);
+	if (n) {
+		lwsl_err("uv_poll_init failed %d, sockfd=%p\n",
+				 n, (void *)(long)wsi->desc.sockfd);
+
+		return -1;
+	}
+	lws_libuv_io(wsi, LWS_EV_START | LWS_EV_READ);
+
+	return 0;
+}
+
+/*
+ * This needs to be called after vhosts have been defined.
+ *
+ * If later, after server start, another vhost is added, this must be
+ * called again to bind the vhost
+ */
 
 LWS_VISIBLE int
 lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi)
 {
 	struct lws_context_per_thread *pt = &context->pt[tsi];
 	struct lws_vhost *vh = context->vhost_list;
-	int status = 0, n, ns;
+	int status = 0, n, ns, first = 1;
 
-	if (!loop) {
-		loop = lws_malloc(sizeof(*loop));
+	if (!pt->io_loop_uv) {
 		if (!loop) {
-			lwsl_err("OOM\n");
-			return -1;
+			loop = lws_malloc(sizeof(*loop));
+			if (!loop) {
+				lwsl_err("OOM\n");
+				return -1;
+			}
+	#if UV_VERSION_MAJOR > 0
+			uv_loop_init(loop);
+	#else
+			lwsl_err("This libuv is too old to work...\n");
+			return 1;
+	#endif
+			pt->ev_loop_foreign = 0;
+		} else {
+			lwsl_notice(" Using foreign event loop...\n");
+			pt->ev_loop_foreign = 1;
 		}
-#if UV_VERSION_MAJOR > 0
-		uv_loop_init(loop);
-#else
-		lwsl_err("This libuv is too old to work...\n");
-		return 1;
-#endif
-		pt->ev_loop_foreign = 0;
-	} else {
-		lwsl_notice(" Using foreign event loop...\n");
-		pt->ev_loop_foreign = 1;
-	}
 
-	pt->io_loop_uv = loop;
-	uv_idle_init(loop, &pt->uv_idle);
+		pt->io_loop_uv = loop;
+		uv_idle_init(loop, &pt->uv_idle);
 
-	ns = ARRAY_SIZE(sigs);
-	if (lws_check_opt(context->options, LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN))
-		ns = 2;
+		ns = ARRAY_SIZE(sigs);
+		if (lws_check_opt(context->options,
+				  LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN))
+			ns = 2;
 
-	if (pt->context->use_ev_sigint) {
-		assert(ns <= ARRAY_SIZE(pt->signals));
-		for (n = 0; n < ns; n++) {
-			uv_signal_init(loop, &pt->signals[n]);
-			pt->signals[n].data = pt->context;
-			uv_signal_start(&pt->signals[n],
-					context->lws_uv_sigint_cb, sigs[n]);
+		if (pt->context->use_ev_sigint) {
+			assert(ns <= ARRAY_SIZE(pt->signals));
+			for (n = 0; n < ns; n++) {
+				uv_signal_init(loop, &pt->signals[n]);
+				pt->signals[n].data = pt->context;
+				uv_signal_start(&pt->signals[n],
+						context->lws_uv_sigint_cb, sigs[n]);
+			}
 		}
-	}
+	} else
+		first = 0;
 
 	/*
 	 * Initialize the accept wsi read watcher with all the listening sockets
@@ -193,24 +237,16 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi)
 	 * initialized until after context creation.
 	 */
 	while (vh) {
-		if (vh->lserv_wsi) {
-			vh->lserv_wsi->w_read.context = context;
-			n = uv_poll_init_socket(pt->io_loop_uv,
-						&vh->lserv_wsi->w_read.uv_watcher,
-						vh->lserv_wsi->sock);
-			if (n) {
-				lwsl_err("uv_poll_init failed %d, sockfd=%p\n",
-					n, (void *)(long)vh->lserv_wsi->sock);
-
-				return -1;
-			}
-			lws_libuv_io(vh->lserv_wsi, LWS_EV_START | LWS_EV_READ);
-		}
+		if (lws_uv_initvhost(vh, vh->lserv_wsi) == -1)
+			return -1;
 		vh = vh->vhost_next;
 	}
 
-	uv_timer_init(pt->io_loop_uv, &pt->uv_timeout_watcher);
-	uv_timer_start(&pt->uv_timeout_watcher, lws_uv_timeout_cb, 10, 1000);
+	if (first) {
+		uv_timer_init(pt->io_loop_uv, &pt->uv_timeout_watcher);
+		uv_timer_start(&pt->uv_timeout_watcher, lws_uv_timeout_cb,
+			       10, 1000);
+	}
 
 	return status;
 }
@@ -222,13 +258,15 @@ 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
 lws_libuv_destroyloop(struct lws_context *context, int tsi)
 {
 	struct lws_context_per_thread *pt = &context->pt[tsi];
+//	struct lws_context *ctx;
 	int m, budget = 100, ns;
 
 	if (!lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV))
@@ -237,6 +275,8 @@ lws_libuv_destroyloop(struct lws_context *context, int tsi)
 	if (!pt->io_loop_uv)
 		return;
 
+	lwsl_notice("%s: closing signals + timers context %p\n", __func__, context);
+
 	if (context->use_ev_sigint) {
 		uv_signal_stop(&pt->w_sigint.uv_watcher);
 
@@ -256,11 +296,13 @@ lws_libuv_destroyloop(struct lws_context *context, int tsi)
 	uv_idle_stop(&pt->uv_idle);
 	uv_close((uv_handle_t *)&pt->uv_idle, lws_uv_close_cb);
 
+	if (pt->ev_loop_foreign)
+		return;
+
 	while (budget-- && uv_run(pt->io_loop_uv, UV_RUN_NOWAIT))
 		;
 
-	if (pt->ev_loop_foreign)
-		return;
+	lwsl_notice("%s: closing all loop handles context %p\n", __func__, context);
 
 	uv_stop(pt->io_loop_uv);
 
@@ -277,7 +319,7 @@ lws_libuv_destroyloop(struct lws_context *context, int tsi)
 }
 
 void
-lws_libuv_accept(struct lws *wsi, lws_sockfd_type accept_fd)
+lws_libuv_accept(struct lws *wsi, lws_sock_file_fd_type desc)
 {
 	struct lws_context *context = lws_get_context(wsi);
 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
@@ -288,8 +330,12 @@ lws_libuv_accept(struct lws *wsi, lws_sockfd_type accept_fd)
 	lwsl_debug("%s: new wsi %p\n", __func__, wsi);
 
 	wsi->w_read.context = context;
-
-	uv_poll_init_socket(pt->io_loop_uv, &wsi->w_read.uv_watcher, accept_fd);
+	if (wsi->mode == LWSCM_RAW_FILEDESC)
+		uv_poll_init(pt->io_loop_uv, &wsi->w_read.uv_watcher,
+			     (int)desc.filefd);
+	else
+		uv_poll_init_socket(pt->io_loop_uv, &wsi->w_read.uv_watcher,
+				    desc.sockfd);
 }
 
 void
@@ -311,7 +357,9 @@ lws_libuv_io(struct lws *wsi, int flags)
 
 	// lwsl_notice("%s: wsi: %p, flags:0x%x\n", __func__, wsi, flags);
 
-	if (!pt->io_loop_uv) {
+	// w->context is set after the loop is initialized
+
+	if (!pt->io_loop_uv || !w->context) {
 		lwsl_info("%s: no io loop yet\n", __func__);
 		return;
 	}
@@ -366,15 +414,24 @@ lws_libuv_run(const struct lws_context *context, int tsi)
 		uv_run(context->pt[tsi].io_loop_uv, 0);
 }
 
+LWS_VISIBLE void
+lws_libuv_stop_without_kill(const struct lws_context *context, int tsi)
+{
+	if (context->pt[tsi].io_loop_uv && LWS_LIBUV_ENABLED(context))
+		uv_stop(context->pt[tsi].io_loop_uv);
+}
+
 static void
 lws_libuv_kill(const struct lws_context *context)
 {
 	int n;
 
+	lwsl_notice("%s\n", __func__);
+
 	for (n = 0; n < context->count_threads; n++)
 		if (context->pt[n].io_loop_uv &&
-		    LWS_LIBUV_ENABLED(context) &&
-		    !context->pt[n].ev_loop_foreign)
+		    LWS_LIBUV_ENABLED(context) )//&&
+		    //!context->pt[n].ev_loop_foreign)
 			uv_stop(context->pt[n].io_loop_uv);
 }
 
@@ -434,9 +491,25 @@ lws_libuv_closewsi(uv_handle_t* handle)
 	struct lws *n = NULL, *wsi = (struct lws *)(((char *)handle) -
 			  (char *)(&n->w_read.uv_watcher));
 	struct lws_context *context = lws_get_context(wsi);
+	int lspd = 0;
+
+	if (wsi->mode == LWSCM_SERVER_LISTENER &&
+	    wsi->context->deprecated) {
+		lspd = 1;
+		context->deprecation_pending_listen_close_count--;
+		if (!context->deprecation_pending_listen_close_count)
+			lspd = 2;
+	}
 
 	lws_close_free_wsi_final(wsi);
 
+	if (lspd == 2 && context->deprecation_cb) {
+		lwsl_notice("calling deprecation callback\n");
+		context->deprecation_cb();
+	}
+
+	//lwsl_notice("%s: ctx %p: wsi left %d\n", __func__, context, context->count_wsi_allocated);
+
 	if (context->requested_kill && context->count_wsi_allocated == 0)
 		lws_libuv_kill(context);
 }
@@ -457,7 +530,7 @@ lws_libuv_closehandle(struct lws *wsi)
 #if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
 
 LWS_VISIBLE int
-lws_plat_plugins_init(struct lws_context * context, const char * const *d)
+lws_plat_plugins_init(struct lws_context *context, const char * const *d)
 {
 	struct lws_plugin_capability lcaps;
 	struct lws_plugin *plugin;
@@ -469,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;
@@ -498,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;
 			}
@@ -546,6 +625,7 @@ bail:
 		d++;
 	}
 
+	uv_run(&loop, UV_RUN_NOWAIT);
 	uv_loop_close(&loop);
 
 	return ret;
@@ -553,13 +633,18 @@ bail:
 }
 
 LWS_VISIBLE int
-lws_plat_plugins_destroy(struct lws_context * context)
+lws_plat_plugins_destroy(struct lws_context *context)
 {
 	struct lws_plugin *plugin = context->plugin_list, *p;
 	lws_plugin_destroy_func func;
 	char path[256];
 	void *v;
 	int m;
+	int pofs = 0;
+
+#if  defined(__MINGW32__) || !defined(WIN32)
+	pofs = 3;
+#endif
 
 	if (!plugin)
 		return 0;
@@ -568,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;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 467 - 88
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/libwebsockets.c


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 476 - 149
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/libwebsockets.h


+ 804 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-esp32.c

@@ -0,0 +1,804 @@
+#include "private-libwebsockets.h"
+#include "freertos/timers.h"
+#include <esp_attr.h>
+/*
+ * included from libwebsockets.c for unix builds
+ */
+
+unsigned long long time_in_microseconds(void)
+{
+	struct timeval tv;
+	gettimeofday(&tv, NULL);
+	return ((unsigned long long)tv.tv_sec * 1000000LL) + tv.tv_usec;
+}
+
+LWS_VISIBLE int
+lws_get_random(struct lws_context *context, void *buf, int len)
+{
+	// !!!
+	return 0;
+}
+
+LWS_VISIBLE int
+lws_send_pipe_choked(struct lws *wsi)
+{
+	fd_set writefds;
+	struct timeval tv = { 0, 0 };
+
+	/* treat the fact we got a truncated send pending as if we're choked */
+	if (wsi->trunc_len)
+		return 1;
+
+	FD_ZERO(&writefds);
+	FD_SET(wsi->desc.sockfd, &writefds);
+
+	if (select(wsi->desc.sockfd + 1, NULL, &writefds, NULL, &tv) < 1)
+		return 1;
+
+	return 0;
+}
+
+LWS_VISIBLE int
+lws_poll_listen_fd(struct lws_pollfd *fd)
+{
+	fd_set readfds;
+	struct timeval tv = { 0, 0 };
+
+	FD_ZERO(&readfds);
+	FD_SET(fd->fd, &readfds);
+
+	return select(fd->fd + 1, &readfds, NULL, NULL, &tv);
+}
+
+LWS_VISIBLE void
+lws_cancel_service_pt(struct lws *wsi)
+{
+}
+
+LWS_VISIBLE void
+lws_cancel_service(struct lws_context *context)
+{
+}
+
+LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
+{
+	printf("%d: %s", level, line);
+}
+
+LWS_VISIBLE LWS_EXTERN int
+_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
+{
+	struct lws_context_per_thread *pt;
+	int n = -1, m, c;
+
+	/* stay dead once we are dead */
+
+	if (!context || !context->vhost_list)
+		return 1;
+
+	pt = &context->pt[tsi];
+
+	if (timeout_ms < 0)
+		goto faked_service;
+
+	if (!context->service_tid_detected) {
+		struct lws _lws;
+
+		memset(&_lws, 0, sizeof(_lws));
+		_lws.context = context;
+
+		context->service_tid_detected =
+			context->vhost_list->protocols[0].callback(
+			&_lws, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
+	}
+	context->service_tid = context->service_tid_detected;
+
+	/*
+	 * is there anybody with pending stuff that needs service forcing?
+	 */
+	if (!lws_service_adjust_timeout(context, 1, tsi)) {
+		/* -1 timeout means just do forced service */
+		_lws_plat_service_tsi(context, -1, pt->tid);
+		/* still somebody left who wants forced service? */
+		if (!lws_service_adjust_timeout(context, 1, pt->tid))
+			/* yes... come back again quickly */
+			timeout_ms = 0;
+	}
+
+//	n = poll(pt->fds, pt->fds_count, timeout_ms);
+	{
+		fd_set readfds, writefds, errfds;
+		struct timeval tv = { timeout_ms / 1000,
+				      (timeout_ms % 1000) * 1000 };
+		int max_fd = 0;
+		FD_ZERO(&readfds);
+		FD_ZERO(&writefds);
+		FD_ZERO(&errfds);
+
+		for (n = 0; n < pt->fds_count; n++) {
+			pt->fds[n].revents = 0;
+			if (pt->fds[n].fd >= max_fd)
+				max_fd = pt->fds[n].fd;
+			if (pt->fds[n].events & LWS_POLLIN)
+				FD_SET(pt->fds[n].fd, &readfds);
+			if (pt->fds[n].events & LWS_POLLOUT)
+				FD_SET(pt->fds[n].fd, &writefds);
+			FD_SET(pt->fds[n].fd, &errfds);
+		}
+
+		n = select(max_fd + 1, &readfds, &writefds, &errfds, &tv);
+		for (n = 0; n < pt->fds_count; n++) {
+			if (FD_ISSET(pt->fds[n].fd, &readfds))
+				pt->fds[n].revents |= LWS_POLLIN;
+			if (FD_ISSET(pt->fds[n].fd, &writefds))
+				pt->fds[n].revents |= LWS_POLLOUT;
+			if (FD_ISSET(pt->fds[n].fd, &errfds))
+				pt->fds[n].revents |= LWS_POLLHUP;
+		}
+	}
+
+
+#ifdef LWS_OPENSSL_SUPPORT
+	if (!pt->rx_draining_ext_list &&
+	    !lws_ssl_anybody_has_buffered_read_tsi(context, tsi) && !n) {
+#else
+	if (!pt->rx_draining_ext_list && !n) /* poll timeout */ {
+#endif
+		lws_service_fd_tsi(context, NULL, tsi);
+		return 0;
+	}
+
+faked_service:
+	m = lws_service_flag_pending(context, tsi);
+	if (m)
+		c = -1; /* unknown limit */
+	else
+		if (n < 0) {
+			if (LWS_ERRNO != LWS_EINTR)
+				return -1;
+			return 0;
+		} else
+			c = n;
+
+	/* any socket with events to service? */
+	for (n = 0; n < pt->fds_count && c; n++) {
+		if (!pt->fds[n].revents)
+			continue;
+
+		c--;
+
+		m = lws_service_fd_tsi(context, &pt->fds[n], tsi);
+		if (m < 0)
+			return -1;
+		/* if something closed, retry this slot */
+		if (m)
+			n--;
+	}
+
+	return 0;
+}
+
+LWS_VISIBLE int
+lws_plat_check_connection_error(struct lws *wsi)
+{
+	return 0;
+}
+
+LWS_VISIBLE int
+lws_plat_service(struct lws_context *context, int timeout_ms)
+{
+	return _lws_plat_service_tsi(context, timeout_ms, 0);
+}
+
+LWS_VISIBLE int
+lws_plat_set_socket_options(struct lws_vhost *vhost, int fd)
+{
+	int optval = 1;
+	socklen_t optlen = sizeof(optval);
+
+#if defined(__APPLE__) || \
+    defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
+    defined(__NetBSD__) || \
+    defined(__OpenBSD__)
+	struct protoent *tcp_proto;
+#endif
+
+	if (vhost->ka_time) {
+		/* enable keepalive on this socket */
+		optval = 1;
+		if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
+			       (const void *)&optval, optlen) < 0)
+			return 1;
+
+#if defined(__APPLE__) || \
+    defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
+    defined(__NetBSD__) || \
+        defined(__CYGWIN__) || defined(__OpenBSD__) || defined (__sun)
+
+		/*
+		 * didn't find a way to set these per-socket, need to
+		 * tune kernel systemwide values
+		 */
+#else
+		/* set the keepalive conditions we want on it too */
+		optval = vhost->ka_time;
+		if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE,
+			       (const void *)&optval, optlen) < 0)
+			return 1;
+
+		optval = vhost->ka_interval;
+		if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL,
+			       (const void *)&optval, optlen) < 0)
+			return 1;
+
+		optval = vhost->ka_probes;
+		if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT,
+			       (const void *)&optval, optlen) < 0)
+			return 1;
+#endif
+	}
+#if 0
+	/* Disable Nagle */
+	optval = 1;
+//	if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *)&optval, optlen) < 0)
+//		return 1;
+	tcp_proto = getprotobyname("TCP");
+	if (setsockopt(fd, tcp_proto->p_proto, TCP_NODELAY, &optval, optlen) < 0)
+		return 1;
+#endif
+	/* We are nonblocking... */
+	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
+		return 1;
+
+	return 0;
+}
+
+LWS_VISIBLE void
+lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
+{
+}
+
+LWS_VISIBLE int
+lws_plat_context_early_init(void)
+{
+	//signal(SIGPIPE, SIG_IGN);
+
+//	signal(SIGABRT, sigabrt_handler);
+
+	return 0;
+}
+
+LWS_VISIBLE void
+lws_plat_context_early_destroy(struct lws_context *context)
+{
+}
+
+LWS_VISIBLE void
+lws_plat_context_late_destroy(struct lws_context *context)
+{
+#ifdef LWS_WITH_PLUGINS
+	if (context->plugin_list)
+		lws_plat_plugins_destroy(context);
+#endif
+
+	if (context->lws_lookup)
+		lws_free(context->lws_lookup);
+}
+
+/* cast a struct sockaddr_in6 * into addr for ipv6 */
+
+LWS_VISIBLE int
+lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
+		    size_t addrlen)
+{
+#if 0
+	int rc = -1;
+
+	struct ifaddrs *ifr;
+	struct ifaddrs *ifc;
+#ifdef LWS_USE_IPV6
+	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
+#endif
+
+	getifaddrs(&ifr);
+	for (ifc = ifr; ifc != NULL && rc; ifc = ifc->ifa_next) {
+		if (!ifc->ifa_addr)
+			continue;
+
+		lwsl_info(" interface %s vs %s\n", ifc->ifa_name, ifname);
+
+		if (strcmp(ifc->ifa_name, ifname))
+			continue;
+
+		switch (ifc->ifa_addr->sa_family) {
+		case AF_INET:
+#ifdef LWS_USE_IPV6
+			if (ipv6) {
+				/* map IPv4 to IPv6 */
+				bzero((char *)&addr6->sin6_addr,
+						sizeof(struct in6_addr));
+				addr6->sin6_addr.s6_addr[10] = 0xff;
+				addr6->sin6_addr.s6_addr[11] = 0xff;
+				memcpy(&addr6->sin6_addr.s6_addr[12],
+					&((struct sockaddr_in *)ifc->ifa_addr)->sin_addr,
+							sizeof(struct in_addr));
+			} else
+#endif
+				memcpy(addr,
+					(struct sockaddr_in *)ifc->ifa_addr,
+						    sizeof(struct sockaddr_in));
+			break;
+#ifdef LWS_USE_IPV6
+		case AF_INET6:
+			memcpy(&addr6->sin6_addr,
+			  &((struct sockaddr_in6 *)ifc->ifa_addr)->sin6_addr,
+						       sizeof(struct in6_addr));
+			break;
+#endif
+		default:
+			continue;
+		}
+		rc = 0;
+	}
+
+	freeifaddrs(ifr);
+
+	if (rc == -1) {
+		/* check if bind to IP address */
+#ifdef LWS_USE_IPV6
+		if (inet_pton(AF_INET6, ifname, &addr6->sin6_addr) == 1)
+			rc = 0;
+		else
+#endif
+		if (inet_pton(AF_INET, ifname, &addr->sin_addr) == 1)
+			rc = 0;
+	}
+
+	return rc;
+#endif
+
+	return -1;
+}
+
+LWS_VISIBLE void
+lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
+{
+	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
+
+	pt->fds[pt->fds_count++].revents = 0;
+}
+
+LWS_VISIBLE void
+lws_plat_delete_socket_from_fds(struct lws_context *context,
+						struct lws *wsi, int m)
+{
+	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
+
+	pt->fds_count--;
+}
+
+LWS_VISIBLE void
+lws_plat_service_periodic(struct lws_context *context)
+{
+}
+
+LWS_VISIBLE int
+lws_plat_change_pollfd(struct lws_context *context,
+		      struct lws *wsi, struct lws_pollfd *pfd)
+{
+	return 0;
+}
+
+LWS_VISIBLE const char *
+lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
+{
+	return inet_ntop(af, src, dst, cnt);
+}
+
+LWS_VISIBLE lws_fop_fd_t IRAM_ATTR
+_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename,
+		    const char *vpath, lws_fop_flags_t *flags)
+{
+	struct stat stat_buf;
+	lws_fop_fd_t fop_fd;
+	int ret = open(filename, *flags, 0664);
+
+	if (ret < 0)
+		return NULL;
+
+	if (fstat(ret, &stat_buf) < 0)
+		goto bail;
+
+	fop_fd = malloc(sizeof(*fop_fd));
+	if (!fop_fd)
+		goto bail;
+
+	fop_fd->fops = fops;
+	fop_fd->fd = ret;
+	fop_fd->flags = *flags;
+	fop_fd->filesystem_priv = NULL; /* we don't use it */
+	fop_fd->pos = 0;
+	fop_fd->len = stat_buf.st_size;
+
+	return fop_fd;
+
+bail:
+	close(ret);
+
+	return NULL;
+}
+
+LWS_VISIBLE int IRAM_ATTR
+_lws_plat_file_close(lws_fop_fd_t *fops_fd)
+{
+	int fd = (*fops_fd)->fd;
+
+	free(*fops_fd);
+	*fops_fd = NULL;
+
+	return close(fd);
+}
+
+LWS_VISIBLE lws_fileofs_t IRAM_ATTR
+_lws_plat_file_seek_cur(lws_fop_fd_t fops_fd, lws_fileofs_t offset)
+{
+	return lseek(fops_fd->fd, offset, SEEK_CUR);
+}
+
+LWS_VISIBLE int IRAM_ATTR
+_lws_plat_file_read(lws_fop_fd_t fops_fd, lws_filepos_t *amount,
+		    uint8_t *buf, lws_filepos_t len)
+{
+	long n;
+
+	n = read(fops_fd->fd, buf, len);
+	if (n == -1) {
+		*amount = 0;
+		return -1;
+	}
+	fops_fd->pos += n;
+	*amount = n;
+
+	return 0;
+}
+
+LWS_VISIBLE int IRAM_ATTR
+_lws_plat_file_write(lws_fop_fd_t fops_fd, lws_filepos_t *amount,
+		     uint8_t *buf, lws_filepos_t len)
+{
+	long n;
+
+	n = write(fops_fd->fd, buf, len);
+	if (n == -1) {
+		*amount = 0;
+		return -1;
+	}
+	fops_fd->pos += n;
+	*amount = n;
+
+	return 0;
+}
+
+
+LWS_VISIBLE int
+lws_plat_init(struct lws_context *context,
+	      struct lws_context_creation_info *info)
+{
+	/* master context has the global fd lookup array */
+	context->lws_lookup = lws_zalloc(sizeof(struct lws *) *
+					 context->max_fds);
+	if (context->lws_lookup == NULL) {
+		lwsl_err("OOM on lws_lookup array for %d connections\n",
+			 context->max_fds);
+		return 1;
+	}
+
+	lwsl_notice(" mem: platform fd map: %5lu bytes\n",
+		    (unsigned long)(sizeof(struct lws *) * context->max_fds));
+
+#ifdef LWS_WITH_PLUGINS
+	if (info->plugin_dirs)
+		lws_plat_plugins_init(context, info->plugin_dirs);
+#endif
+
+	return 0;
+}
+
+
+LWS_VISIBLE void esp32_uvtimer_cb(TimerHandle_t t)
+{
+	struct timer_mapping *p = pvTimerGetTimerID(t);
+
+	p->cb(p->t);
+}
+
+void ERR_error_string_n(unsigned long e, char *buf, size_t len)
+{
+	strncpy(buf, "unknown", len);
+}
+
+void ERR_free_strings(void)
+{
+}
+
+char *ERR_error_string(unsigned long e, char *buf)
+{
+	if (buf)
+		strcpy(buf, "unknown");
+
+	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;
+}
+

+ 11 - 11
EVSE/GPL/libwebsockets-v2.1-stable/lib/lws-plat-esp8266.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-esp8266.c

@@ -72,7 +72,7 @@ lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)
 	//lwsl_notice("%s: wsi %p: len %d\n", __func__, wsi, len);	
 	
 	wsi->pending_send_completion++;
-	espconn_send(wsi->sock, buf, len);
+	espconn_send(wsi->desc.sockfd, buf, len);
 	
 	return len;
 }
@@ -188,7 +188,7 @@ LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
 }
 
 LWS_VISIBLE LWS_EXTERN int
-lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
+_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 {
 	return 0;
 }
@@ -202,7 +202,7 @@ lws_plat_check_connection_error(struct lws *wsi)
 LWS_VISIBLE int
 lws_plat_service(struct lws_context *context, int timeout_ms)
 {
-//	return lws_plat_service_tsi(context, timeout_ms, 0);
+//	return _lws_plat_service_tsi(context, timeout_ms, 0);
 	return 0;
 }
 
@@ -247,7 +247,7 @@ esp8266_create_tcp_listen_socket(struct lws_vhost *vh)
 const char *
 lws_plat_get_peer_simple(struct lws *wsi, char *name, int namelen)
 {
-	unsigned char *p = wsi->sock->proto.tcp->remote_ip;
+	unsigned char *p = wsi->desc.sockfd->proto.tcp->remote_ip;
 
 	lws_snprintf(name, namelen, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);
 
@@ -493,7 +493,7 @@ esp8266_tcp_stream_accept(lws_sockfd_type fd, struct lws *wsi)
 	fd->reverse = wsi;
 
 	for (n = 0; n < wsi->context->max_fds ; n++)
-		if (wsi->context->connpool[n] == wsi->sock)
+		if (wsi->context->connpool[n] == wsi->desc.sockfd)
 			wsi->position_in_fds_table = n;
 }
 
@@ -555,7 +555,7 @@ lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
 	struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
 
 	context->connpool[wsi->position_in_fds_table + context->max_fds] = (lws_sockfd_type)wsi;
-	wsi->sock->reverse = wsi;
+	wsi->desc.sockfd->reverse = wsi;
 	pt->fds_count++;
 }
 
@@ -567,13 +567,13 @@ lws_plat_delete_socket_from_fds(struct lws_context *context,
 	int n;
 	
 	for (n = 0; n < wsi->context->max_fds; n++)
-		if (wsi->context->connpool[n] == wsi->sock) {
+		if (wsi->context->connpool[n] == wsi->desc.sockfd) {
 			wsi->context->connpool[n] = NULL;
 			wsi->context->connpool[n + wsi->context->max_fds] = NULL;
 			lwsl_notice(" freed connpool %d\n", n);
 		}
 	
-	wsi->sock->reverse = NULL;
+	wsi->desc.sockfd->reverse = NULL;
 	pt->fds_count--;
 }
 
@@ -596,17 +596,17 @@ lws_plat_change_pollfd(struct lws_context *context,
 			lwsl_notice("replaying buffered rx: wsi %p\n", wsi);
 			p = wsi->premature_rx;
 			wsi->premature_rx = NULL;
-			esp8266_cb_rx(wsi->sock,
+			esp8266_cb_rx(wsi->desc.sockfd,
 				      (char *)p + wsi->prem_rx_pos,
 				      wsi->prem_rx_size - wsi->prem_rx_pos);
 			wsi->prem_rx_size = 0;
 			wsi->prem_rx_pos = 0;
 			lws_free(p);
 		}
-		if (espconn_recv_unhold(wsi->sock) < 0)
+		if (espconn_recv_unhold(wsi->desc.sockfd) < 0)
 			return -1;
 	} else
-		if (espconn_recv_hold(wsi->sock) < 0)
+		if (espconn_recv_hold(wsi->desc.sockfd) < 0)
 			return -1;
 	
 	if (!(pfd->events & LWS_POLLOUT))

+ 322 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-optee.c

@@ -0,0 +1,322 @@
+#include "private-libwebsockets.h"
+
+/*
+ * included from libwebsockets.c for OPTEE builds
+ */
+
+void TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen);
+
+unsigned long long time_in_microseconds(void)
+{
+	return ((unsigned long long)time(NULL)) * 1000000;
+}
+#if 0
+LWS_VISIBLE int
+lws_get_random(struct lws_context *context, void *buf, int len)
+{
+	TEE_GenerateRandom(buf, len);
+
+	return len;
+}
+#endif
+LWS_VISIBLE int
+lws_send_pipe_choked(struct lws *wsi)
+{
+#if 0
+	struct lws_pollfd fds;
+
+	/* treat the fact we got a truncated send pending as if we're choked */
+	if (wsi->trunc_len)
+		return 1;
+
+	fds.fd = wsi->desc.sockfd;
+	fds.events = POLLOUT;
+	fds.revents = 0;
+
+	if (poll(&fds, 1, 0) != 1)
+		return 1;
+
+	if ((fds.revents & POLLOUT) == 0)
+		return 1;
+#endif
+	/* okay to send another packet without blocking */
+
+	return 0;
+}
+
+LWS_VISIBLE int
+lws_poll_listen_fd(struct lws_pollfd *fd)
+{
+//	return poll(fd, 1, 0);
+
+	return 0;
+}
+
+LWS_VISIBLE void
+lws_cancel_service_pt(struct lws *wsi)
+{
+#if 0
+	struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
+	char buf = 0;
+
+	if (write(pt->dummy_pipe_fds[1], &buf, sizeof(buf)) != 1)
+		lwsl_err("Cannot write to dummy pipe");
+#endif
+}
+
+LWS_VISIBLE void
+lws_cancel_service(struct lws_context *context)
+{
+#if 0
+	struct lws_context_per_thread *pt = &context->pt[0];
+	char buf = 0, m = context->count_threads;
+
+	while (m--) {
+		if (write(pt->dummy_pipe_fds[1], &buf, sizeof(buf)) != 1)
+			lwsl_err("Cannot write to dummy pipe");
+		pt++;
+	}
+#endif
+}
+#if 0
+LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
+{
+	IMSG("%d: %s\n", level, line);
+}
+#endif
+
+LWS_VISIBLE LWS_EXTERN int
+_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
+{
+	struct lws_context_per_thread *pt;
+	int n = -1, m, c;
+	//char buf;
+
+	/* stay dead once we are dead */
+
+	if (!context || !context->vhost_list)
+		return 1;
+
+	pt = &context->pt[tsi];
+
+	if (timeout_ms < 0)
+		goto faked_service;
+
+	if (!context->service_tid_detected) {
+		struct lws _lws;
+
+		memset(&_lws, 0, sizeof(_lws));
+		_lws.context = context;
+
+		context->service_tid_detected =
+			context->vhost_list->protocols[0].callback(
+			&_lws, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
+	}
+	context->service_tid = context->service_tid_detected;
+
+	/*
+	 * is there anybody with pending stuff that needs service forcing?
+	 */
+	if (!lws_service_adjust_timeout(context, 1, tsi)) {
+		lwsl_notice("%s: doing forced service\n", __func__);
+		/* -1 timeout means just do forced service */
+		_lws_plat_service_tsi(context, -1, pt->tid);
+		/* still somebody left who wants forced service? */
+		if (!lws_service_adjust_timeout(context, 1, pt->tid))
+			/* yes... come back again quickly */
+			timeout_ms = 0;
+	}
+#if 1
+	n = poll(pt->fds, pt->fds_count, timeout_ms);
+
+#ifdef LWS_OPENSSL_SUPPORT
+	if (!pt->rx_draining_ext_list &&
+	    !lws_ssl_anybody_has_buffered_read_tsi(context, tsi) && !n) {
+#else
+	if (!pt->rx_draining_ext_list && !n) /* poll timeout */ {
+#endif
+		lws_service_fd_tsi(context, NULL, tsi);
+		return 0;
+	}
+#endif
+faked_service:
+	m = lws_service_flag_pending(context, tsi);
+	if (m)
+		c = -1; /* unknown limit */
+	else
+		if (n < 0) {
+			if (LWS_ERRNO != LWS_EINTR)
+				return -1;
+			return 0;
+		} else
+			c = n;
+
+	/* any socket with events to service? */
+	for (n = 0; n < pt->fds_count && c; n++) {
+		if (!pt->fds[n].revents)
+			continue;
+
+		c--;
+#if 0
+		if (pt->fds[n].fd == pt->dummy_pipe_fds[0]) {
+			if (read(pt->fds[n].fd, &buf, 1) != 1)
+				lwsl_err("Cannot read from dummy pipe.");
+			continue;
+		}
+#endif
+		m = lws_service_fd_tsi(context, &pt->fds[n], tsi);
+		if (m < 0)
+			return -1;
+		/* if something closed, retry this slot */
+		if (m)
+			n--;
+	}
+
+	return 0;
+}
+
+LWS_VISIBLE int
+lws_plat_check_connection_error(struct lws *wsi)
+{
+	return 0;
+}
+
+LWS_VISIBLE int
+lws_plat_service(struct lws_context *context, int timeout_ms)
+{
+	return _lws_plat_service_tsi(context, timeout_ms, 0);
+}
+
+LWS_VISIBLE int
+lws_plat_set_socket_options(struct lws_vhost *vhost, int fd)
+{
+	return 0;
+}
+
+LWS_VISIBLE void
+lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
+{
+}
+
+LWS_VISIBLE int
+lws_plat_context_early_init(void)
+{
+	return 0;
+}
+
+LWS_VISIBLE void
+lws_plat_context_early_destroy(struct lws_context *context)
+{
+}
+
+LWS_VISIBLE void
+lws_plat_context_late_destroy(struct lws_context *context)
+{
+	if (context->lws_lookup)
+		lws_free(context->lws_lookup);
+}
+
+/* cast a struct sockaddr_in6 * into addr for ipv6 */
+
+LWS_VISIBLE int
+lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
+		    size_t addrlen)
+{
+	return -1;
+}
+
+LWS_VISIBLE void
+lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
+{
+	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
+
+	pt->fds[pt->fds_count++].revents = 0;
+}
+
+LWS_VISIBLE void
+lws_plat_delete_socket_from_fds(struct lws_context *context,
+						struct lws *wsi, int m)
+{
+	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
+
+	pt->fds_count--;
+}
+
+LWS_VISIBLE void
+lws_plat_service_periodic(struct lws_context *context)
+{
+}
+
+LWS_VISIBLE int
+lws_plat_change_pollfd(struct lws_context *context,
+		      struct lws *wsi, struct lws_pollfd *pfd)
+{
+	return 0;
+}
+
+LWS_VISIBLE const char *
+lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
+{
+	//return inet_ntop(af, src, dst, cnt);
+	return "lws_plat_inet_ntop";
+}
+
+LWS_VISIBLE lws_fop_fd_t
+_lws_plat_file_open(lws_plat_file_open(struct lws_plat_file_ops *fops,
+		    const char *filename, lws_fop_flags_t *flags)
+{
+	return NULL;
+}
+
+LWS_VISIBLE int
+_lws_plat_file_close(lws_fop_fd_t *fop_fd)
+{
+	return 0;
+}
+
+LWS_VISIBLE lws_fileofs_t
+_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
+{
+	return 0;
+}
+
+LWS_VISIBLE  int
+_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+		    uint8_t *buf, lws_filepos_t len)
+{
+
+	return 0;
+}
+
+LWS_VISIBLE  int
+_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+		     uint8_t *buf, lws_filepos_t len)
+{
+
+	return 0;
+}
+
+
+LWS_VISIBLE int
+lws_plat_init(struct lws_context *context,
+	      struct lws_context_creation_info *info)
+{
+	/* master context has the global fd lookup array */
+	context->lws_lookup = lws_zalloc(sizeof(struct lws *) *
+					 context->max_fds);
+	if (context->lws_lookup == NULL) {
+		lwsl_err("OOM on lws_lookup array for %d connections\n",
+			 context->max_fds);
+		return 1;
+	}
+
+	lwsl_notice(" mem: platform fd map: %5lu bytes\n",
+		    (long)sizeof(struct lws *) * context->max_fds);
+
+#ifdef LWS_WITH_PLUGINS
+	if (info->plugin_dirs)
+		lws_plat_plugins_init(context, info->plugin_dirs);
+#endif
+
+	return 0;
+}

+ 80 - 41
EVSE/GPL/libwebsockets-v2.1-stable/lib/lws-plat-unix.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-unix.c

@@ -35,7 +35,7 @@ lws_send_pipe_choked(struct lws *wsi)
 	if (wsi->trunc_len)
 		return 1;
 
-	fds.fd = wsi->sock;
+	fds.fd = wsi->desc.sockfd;
 	fds.events = POLLOUT;
 	fds.revents = 0;
 
@@ -101,9 +101,9 @@ LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
 }
 
 LWS_VISIBLE LWS_EXTERN int
-lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
+_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 {
-	struct lws_context_per_thread *pt = &context->pt[tsi];
+	struct lws_context_per_thread *pt;
 	int n = -1, m, c;
 	char buf;
 
@@ -112,6 +112,8 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 	if (!context || !context->vhost_list)
 		return 1;
 
+	pt = &context->pt[tsi];
+
 	if (timeout_ms < 0)
 		goto faked_service;
 
@@ -135,7 +137,7 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 	 */
 	if (!lws_service_adjust_timeout(context, 1, tsi)) {
 		/* -1 timeout means just do forced service */
-		lws_plat_service_tsi(context, -1, pt->tid);
+		_lws_plat_service_tsi(context, -1, pt->tid);
 		/* still somebody left who wants forced service? */
 		if (!lws_service_adjust_timeout(context, 1, pt->tid))
 			/* yes... come back again quickly */
@@ -199,7 +201,7 @@ lws_plat_check_connection_error(struct lws *wsi)
 LWS_VISIBLE int
 lws_plat_service(struct lws_context *context, int timeout_ms)
 {
-	return lws_plat_service_tsi(context, timeout_ms, 0);
+	return _lws_plat_service_tsi(context, timeout_ms, 0);
 }
 
 LWS_VISIBLE int
@@ -479,11 +481,16 @@ lws_plat_context_late_destroy(struct lws_context *context)
 		lws_free(context->lws_lookup);
 
 	while (m--) {
-		close(pt->dummy_pipe_fds[0]);
-		close(pt->dummy_pipe_fds[1]);
+		if (pt->dummy_pipe_fds[0])
+			close(pt->dummy_pipe_fds[0]);
+		if (pt->dummy_pipe_fds[1])
+			close(pt->dummy_pipe_fds[1]);
 		pt++;
 	}
-	close(context->fd_random);
+	if (!context->fd_random)
+		lwsl_err("ZERO RANDOM FD\n");
+	if (context->fd_random != LWS_INVALID_FILE)
+		close(context->fd_random);
 }
 
 /* cast a struct sockaddr_in6 * into addr for ipv6 */
@@ -602,65 +609,103 @@ lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
 	return inet_ntop(af, src, dst, cnt);
 }
 
-static lws_filefd_type
-_lws_plat_file_open(struct lws *wsi, const char *filename,
-		    unsigned long *filelen, int flags)
+LWS_VISIBLE lws_fop_fd_t
+_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename,
+		    const char *vpath, lws_fop_flags_t *flags)
 {
 	struct stat stat_buf;
-	int ret = open(filename, flags, 0664);
+	int ret = open(filename, (*flags) & LWS_FOP_FLAGS_MASK, 0664);
+	lws_fop_fd_t fop_fd;
 
 	if (ret < 0)
-		return LWS_INVALID_FILE;
+		return NULL;
 
-	if (fstat(ret, &stat_buf) < 0) {
-		close(ret);
-		return LWS_INVALID_FILE;
-	}
-	*filelen = stat_buf.st_size;
-	return ret;
+	if (fstat(ret, &stat_buf) < 0)
+		goto bail;
+
+	fop_fd = malloc(sizeof(*fop_fd));
+	if (!fop_fd)
+		goto bail;
+
+	fop_fd->fops = fops;
+	fop_fd->flags = *flags;
+	fop_fd->fd = ret;
+	fop_fd->filesystem_priv = NULL; /* we don't use it */
+	fop_fd->len = stat_buf.st_size;
+	fop_fd->pos = 0;
+
+	return fop_fd;
+
+bail:
+	close(ret);
+	return NULL;
 }
 
-static int
-_lws_plat_file_close(struct lws *wsi, lws_filefd_type fd)
+LWS_VISIBLE int
+_lws_plat_file_close(lws_fop_fd_t *fop_fd)
 {
+	int fd = (*fop_fd)->fd;
+
+	free(*fop_fd);
+	*fop_fd = NULL;
+
 	return close(fd);
 }
 
-unsigned long
-_lws_plat_file_seek_cur(struct lws *wsi, lws_filefd_type fd, long offset)
+LWS_VISIBLE lws_fileofs_t
+_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
 {
-	return lseek(fd, offset, SEEK_CUR);
+	lws_fileofs_t r;
+
+	if (offset > 0 && offset > fop_fd->len - fop_fd->pos)
+		offset = fop_fd->len - fop_fd->pos;
+
+	if ((lws_fileofs_t)fop_fd->pos + offset < 0)
+		offset = -fop_fd->pos;
+
+	r = lseek(fop_fd->fd, offset, SEEK_CUR);
+
+	if (r >= 0)
+		fop_fd->pos = r;
+	else
+		lwsl_err("error seeking from cur %ld, offset %ld\n",
+                        (long)fop_fd->pos, (long)offset);
+
+	return r;
 }
 
-static int
-_lws_plat_file_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
-		    unsigned char *buf, unsigned long len)
+LWS_VISIBLE int
+_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+		    uint8_t *buf, lws_filepos_t len)
 {
 	long n;
 
-	n = read((int)fd, buf, len);
+	n = read((int)fop_fd->fd, buf, len);
 	if (n == -1) {
 		*amount = 0;
 		return -1;
 	}
-
+	fop_fd->pos += n;
+	lwsl_debug("%s: read %ld of req %ld, pos %ld, len %ld\n", __func__, n,
+                  (long)len, (long)fop_fd->pos, (long)fop_fd->len);
 	*amount = n;
 
 	return 0;
 }
 
-static int
-_lws_plat_file_write(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
-		     unsigned char *buf, unsigned long len)
+LWS_VISIBLE int
+_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+		     uint8_t *buf, lws_filepos_t len)
 {
 	long n;
 
-	n = write((int)fd, buf, len);
+	n = write((int)fop_fd->fd, buf, len);
 	if (n == -1) {
 		*amount = 0;
 		return -1;
 	}
 
+	fop_fd->pos += n;
 	*amount = n;
 
 	return 0;
@@ -683,8 +728,8 @@ lws_plat_init(struct lws_context *context,
 		return 1;
 	}
 
-	lwsl_notice(" mem: platform fd map: %5u bytes\n",
-		    sizeof(struct lws *) * context->max_fds);
+	lwsl_notice(" mem: platform fd map: %5lu bytes\n",
+		    (unsigned long)(sizeof(struct lws *) * context->max_fds));
 	fd = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
 
 	context->fd_random = fd;
@@ -713,12 +758,6 @@ lws_plat_init(struct lws_context *context,
 		}
 	}
 
-	context->fops.open	= _lws_plat_file_open;
-	context->fops.close	= _lws_plat_file_close;
-	context->fops.seek_cur	= _lws_plat_file_seek_cur;
-	context->fops.read	= _lws_plat_file_read;
-	context->fops.write	= _lws_plat_file_write;
-
 #ifdef LWS_WITH_PLUGINS
 	if (info->plugin_dirs)
 		lws_plat_plugins_init(context, info->plugin_dirs);

+ 77 - 44
EVSE/GPL/libwebsockets-v2.1-stable/lib/lws-plat-win.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/lws-plat-win.c

@@ -6,7 +6,9 @@
 unsigned long long
 time_in_microseconds()
 {
+#ifndef DELTA_EPOCH_IN_MICROSECS
 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
+#endif
 	FILETIME filetime;
 	ULARGE_INTEGER datetime;
 
@@ -48,7 +50,7 @@ wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd)
 	int n = 0;
 
 	for (n = 0; n < context->fd_hashtable[h].length; n++)
-		if (context->fd_hashtable[h].wsi[n]->sock == fd)
+		if (context->fd_hashtable[h].wsi[n]->desc.sockfd == fd)
 			return context->fd_hashtable[h].wsi[n];
 
 	return NULL;
@@ -57,7 +59,7 @@ wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd)
 int
 insert_wsi(struct lws_context *context, struct lws *wsi)
 {
-	int h = LWS_FD_HASH(wsi->sock);
+	int h = LWS_FD_HASH(wsi->desc.sockfd);
 
 	if (context->fd_hashtable[h].length == (getdtablesize() - 1)) {
 		lwsl_err("hash table overflow\n");
@@ -76,7 +78,7 @@ delete_from_fd(struct lws_context *context, lws_sockfd_type fd)
 	int n = 0;
 
 	for (n = 0; n < context->fd_hashtable[h].length; n++)
-		if (context->fd_hashtable[h].wsi[n]->sock == fd) {
+		if (context->fd_hashtable[h].wsi[n]->desc.sockfd == fd) {
 			while (n < context->fd_hashtable[h].length) {
 				context->fd_hashtable[h].wsi[n] =
 						context->fd_hashtable[h].wsi[n + 1];
@@ -106,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;
 }
 
@@ -147,9 +153,9 @@ LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
 }
 
 LWS_VISIBLE LWS_EXTERN int
-lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
+_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 {
-	struct lws_context_per_thread *pt = &context->pt[tsi];
+	struct lws_context_per_thread *pt;
 	WSANETWORKEVENTS networkevents;
 	struct lws_pollfd *pfd;
 	struct lws *wsi;
@@ -161,6 +167,8 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 	if (context == NULL)
 		return 1;
 
+	pt = &context->pt[tsi];
+
 	if (!context->service_tid_detected) {
 		struct lws _lws;
 
@@ -217,7 +225,7 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 	 */
 	if (!lws_service_adjust_timeout(context, 1, tsi)) {
 		/* -1 timeout means just do forced service */
-		lws_plat_service_tsi(context, -1, pt->tid);
+		_lws_plat_service_tsi(context, -1, pt->tid);
 		/* still somebody left who wants forced service? */
 		if (!lws_service_adjust_timeout(context, 1, pt->tid))
 			/* yes... come back again quickly */
@@ -226,10 +234,11 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 
 	ev = WSAWaitForMultipleEvents( 1,  pt->events , FALSE, timeout_ms, FALSE);
 	if (ev == WSA_WAIT_EVENT_0) {
+		unsigned int eIdx;
 
 		WSAResetEvent(pt->events[0]);
 
-		for(unsigned int eIdx = 0; eIdx < pt->fds_count; ++eIdx) {
+		for (eIdx = 0; eIdx < pt->fds_count; ++eIdx) {
 			if (WSAEnumNetworkEvents(pt->fds[eIdx].fd, 0, &networkevents) == SOCKET_ERROR) {
 				lwsl_err("WSAEnumNetworkEvents() failed with error %d\n", LWS_ERRNO);
 				return -1;
@@ -277,7 +286,7 @@ lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 LWS_VISIBLE int
 lws_plat_service(struct lws_context *context, int timeout_ms)
 {
-	return lws_plat_service_tsi(context, timeout_ms, 0);
+	return _lws_plat_service_tsi(context, timeout_ms, 0);
 }
 
 LWS_VISIBLE int
@@ -412,7 +421,7 @@ lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
 
 	pt->fds[pt->fds_count++].revents = 0;
 	pt->events[pt->fds_count] = pt->events[0];
-	WSAEventSelect(wsi->sock, pt->events[0],
+	WSAEventSelect(wsi->desc.sockfd, pt->events[0],
 			   LWS_POLLIN | LWS_POLLHUP | FD_CONNECT);
 }
 
@@ -436,7 +445,7 @@ lws_plat_check_connection_error(struct lws *wsi)
 	int optVal;
 	int optLen = sizeof(int);
 
-	if (getsockopt(wsi->sock, SOL_SOCKET, SO_ERROR,
+	if (getsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_ERROR,
 			   (char*)&optVal, &optLen) != SOCKET_ERROR && optVal &&
 		optVal != LWS_EALREADY && optVal != LWS_EINPROGRESS &&
 		optVal != LWS_EWOULDBLOCK && optVal != WSAEINVAL) {
@@ -460,7 +469,7 @@ lws_plat_change_pollfd(struct lws_context *context,
 	if ((pfd->events & LWS_POLLOUT))
 		networkevents |= LWS_POLLOUT;
 
-	if (WSAEventSelect(wsi->sock,
+	if (WSAEventSelect(wsi->desc.sockfd,
 			pt->events[0],
 						   networkevents) != SOCKET_ERROR)
 		return 0;
@@ -516,75 +525,91 @@ lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
 	return ok ? dst : NULL;
 }
 
-static lws_filefd_type
-_lws_plat_file_open(struct lws *wsi, const char *filename,
-			unsigned long *filelen, int flags)
+LWS_VISIBLE lws_fop_fd_t
+_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename,
+		    const char *vpath, lws_fop_flags_t *flags)
 {
 	HANDLE ret;
 	WCHAR buf[MAX_PATH];
+	lws_fop_fd_t fop_fd;
 
-	(void)wsi;
 	MultiByteToWideChar(CP_UTF8, 0, filename, -1, buf, ARRAY_SIZE(buf));
-	if ((flags & 7) == _O_RDONLY) {
+	if (((*flags) & 7) == _O_RDONLY) {
 		ret = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ,
 			  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 	} else {
 		lwsl_err("%s: open for write not implemented\n", __func__);
-		*filelen = 0;
-		return LWS_INVALID_FILE;
+		goto bail;
 	}
 
-	if (ret != LWS_INVALID_FILE)
-		*filelen = GetFileSize(ret, NULL);
+	if (ret == LWS_INVALID_FILE)
+		goto bail;
 
-	return ret;
+	fop_fd = malloc(sizeof(*fop_fd));
+	if (!fop_fd)
+		goto bail;
+
+	fop_fd->fops = fops;
+	fop_fd->fd = ret;
+	fop_fd->filesystem_priv = NULL; /* we don't use it */
+	fop_fd->flags = *flags;
+	fop_fd->len = GetFileSize(ret, NULL);
+	fop_fd->pos = 0;
+
+	return fop_fd;
+
+bail:
+	return NULL;
 }
 
-static int
-_lws_plat_file_close(struct lws *wsi, lws_filefd_type fd)
+LWS_VISIBLE int
+_lws_plat_file_close(lws_fop_fd_t *fop_fd)
 {
-	(void)wsi;
+	HANDLE fd = (*fop_fd)->fd;
+
+	free(*fop_fd);
+	*fop_fd = NULL;
 
 	CloseHandle((HANDLE)fd);
 
 	return 0;
 }
 
-static unsigned long
-_lws_plat_file_seek_cur(struct lws *wsi, lws_filefd_type fd, long offset)
+LWS_VISIBLE lws_fileofs_t
+_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
 {
-	(void)wsi;
-
-	return SetFilePointer((HANDLE)fd, offset, NULL, FILE_CURRENT);
+	return SetFilePointer((HANDLE)fop_fd->fd, offset, NULL, FILE_CURRENT);
 }
 
-static int
-_lws_plat_file_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
-			unsigned char* buf, unsigned long len)
+LWS_VISIBLE int
+_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+		    uint8_t *buf, lws_filepos_t len)
 {
 	DWORD _amount;
 
-	if (!ReadFile((HANDLE)fd, buf, (DWORD)len, &_amount, NULL)) {
+	if (!ReadFile((HANDLE)fop_fd->fd, buf, (DWORD)len, &_amount, NULL)) {
 		*amount = 0;
 
 		return 1;
 	}
 
+	fop_fd->pos += _amount;
 	*amount = (unsigned long)_amount;
 
 	return 0;
 }
 
-static int
-_lws_plat_file_write(struct lws *wsi, lws_filefd_type fd, unsigned long *amount,
-			 unsigned char* buf, unsigned long len)
+LWS_VISIBLE int
+_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
+			 uint8_t* buf, lws_filepos_t len)
 {
-	(void)wsi;
-	(void)fd;
+	(void)fop_fd;
 	(void)amount;
 	(void)buf;
 	(void)len;
 
+	fop_fd->pos += len;
+
 	lwsl_err("%s: not implemented yet on this platform\n", __func__);
 
 	return -1;
@@ -622,12 +647,6 @@ lws_plat_init(struct lws_context *context,
 
 	context->fd_random = 0;
 
-	context->fops.open	= _lws_plat_file_open;
-	context->fops.close	= _lws_plat_file_close;
-	context->fops.seek_cur	= _lws_plat_file_seek_cur;
-	context->fops.read	= _lws_plat_file_read;
-	context->fops.write	= _lws_plat_file_write;
-
 #ifdef LWS_WITH_PLUGINS
 	if (info->plugin_dirs)
 		lws_plat_plugins_init(context, info->plugin_dirs);
@@ -635,3 +654,17 @@ lws_plat_init(struct lws_context *context,
 
 	return 0;
 }
+
+
+int kill(int pid, int sig)
+{
+	lwsl_err("Sorry Windows doesn't support kill().");
+	exit(0);
+}
+
+int fork(void)
+{
+	lwsl_err("Sorry Windows doesn't support fork().");
+	exit(0);
+}
+

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/minihuf.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/minihuf.c


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/minilex.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/minilex.c


+ 123 - 35
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/output.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/output.c

@@ -112,13 +112,13 @@ int lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len)
 		strncpy(dump, (char *)buf, sizeof(dump) - 1);
 		dump[sizeof(dump) - 1] = '\0';
 #if defined(LWS_WITH_ESP8266)
-		lwsl_err("****** %p: Sending new %d (%s), pending truncated ...\n",
-			 wsi, len, dump);
+		lwsl_err("****** %p: Sending new %lu (%s), pending truncated ...\n",
+			 wsi, (unsigned long)len, dump);
 #else
-		lwsl_err("****** %p: Sending new %d (%s), pending truncated ...\n"
+		lwsl_err("****** %p: Sending new %lu (%s), pending truncated ...\n"
 			 "       It's illegal to do an lws_write outside of\n"
 			 "       the writable callback: fix your code",
-			 wsi, len, dump);
+			 wsi, (unsigned long)len, dump);
 #endif
 		assert(0);
 
@@ -133,7 +133,7 @@ int lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len)
 		goto handle_truncated_send;
 	}
 
-	if (!lws_socket_is_valid(wsi->sock))
+	if (!lws_socket_is_valid(wsi->desc.sockfd))
 		lwsl_warn("** error invalid sock but expected to send\n");
 
 	/* limit sending */
@@ -171,16 +171,16 @@ handle_truncated_send:
 	 * we were already handling a truncated send?
 	 */
 	if (wsi->trunc_len) {
-		lwsl_info("%p partial adv %d (vs %d)\n", wsi, n, real_len);
+		lwsl_info("%p partial adv %d (vs %ld)\n", wsi, n, (long)real_len);
 		wsi->trunc_offset += n;
 		wsi->trunc_len -= n;
 
 		if (!wsi->trunc_len) {
-			lwsl_info("***** %x partial send completed\n", wsi);
+			lwsl_info("***** %p partial send completed\n", wsi);
 			/* done with it, but don't free it */
 			n = real_len;
 			if (wsi->state == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
-				lwsl_info("***** %x signalling to close now\n", wsi);
+				lwsl_info("***** %p signalling to close now\n", wsi);
 				return -1; /* retry closing now */
 			}
 		}
@@ -198,7 +198,8 @@ handle_truncated_send:
 	 * Newly truncated send.  Buffer the remainder (it will get
 	 * first priority next time the socket is writable)
 	 */
-	lwsl_notice("%p new partial sent %d from %d total\n", wsi, n, real_len);
+	lwsl_info("%p new partial sent %d from %lu total\n", wsi, n,
+		    (unsigned long)real_len);
 
 	/*
 	 *  - if we still have a suitable malloc lying around, use it
@@ -211,8 +212,8 @@ handle_truncated_send:
 		wsi->trunc_alloc_len = real_len - n;
 		wsi->trunc_alloc = lws_malloc(real_len - n);
 		if (!wsi->trunc_alloc) {
-			lwsl_err("truncated send: unable to malloc %d\n",
-				 real_len - n);
+			lwsl_err("truncated send: unable to malloc %lu\n",
+				 (unsigned long)(real_len - n));
 			return -1;
 		}
 	}
@@ -241,7 +242,7 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len,
 	wsi->access_log.sent += len;
 #endif
 	if (wsi->vhost)
-		wsi->vhost->tx += len;
+		wsi->vhost->conn_stats.tx += len;
 
 	if (wsi->state == LWSS_ESTABLISHED && wsi->u.ws.tx_draining_ext) {
 		/* remove us from the list */
@@ -491,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;
@@ -557,19 +558,23 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
 	struct lws_context *context = wsi->context;
 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
 	struct lws_process_html_args args;
-	unsigned long amount, poss;
-	unsigned char *p = pt->serv_buf;
+	lws_filepos_t amount, poss;
+	unsigned char *p;
+#if defined(LWS_WITH_RANGES)
+	unsigned char finished = 0;
+#endif
 	int n, m;
-	
+
 	// lwsl_notice("%s (trunc len %d)\n", __func__, wsi->trunc_len);
 
 	while (wsi->http2_substream || !lws_send_pipe_choked(wsi)) {
+
 		if (wsi->trunc_len) {
 			if (lws_issue_raw(wsi, wsi->trunc_alloc +
 					  wsi->trunc_offset,
 					  wsi->trunc_len) < 0) {
 				lwsl_info("%s: closing\n", __func__);
-				return -1;
+				goto file_had_it;
 			}
 			continue;
 		}
@@ -577,8 +582,50 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
 		if (wsi->u.http.filepos == wsi->u.http.filelen)
 			goto all_sent;
 
-		poss = context->pt_serv_buf_size;
+		n = 0;
+
+		p = pt->serv_buf;
+
+#if defined(LWS_WITH_RANGES)
+		if (wsi->u.http.range.count_ranges && !wsi->u.http.range.inside) {
+
+			lwsl_notice("%s: doing range start %llu\n", __func__, wsi->u.http.range.start);
 
+			if ((long)lws_vfs_file_seek_cur(wsi->u.http.fop_fd,
+						   wsi->u.http.range.start -
+						   wsi->u.http.filepos) < 0)
+				goto file_had_it;
+
+			wsi->u.http.filepos = wsi->u.http.range.start;
+
+			if (wsi->u.http.range.count_ranges > 1) {
+				n =  lws_snprintf((char *)p, context->pt_serv_buf_size,
+					"_lws\x0d\x0a"
+					"Content-Type: %s\x0d\x0a"
+					"Content-Range: bytes %llu-%llu/%llu\x0d\x0a"
+					"\x0d\x0a",
+					wsi->u.http.multipart_content_type,
+					wsi->u.http.range.start,
+					wsi->u.http.range.end,
+					wsi->u.http.range.extent);
+				p += n;
+			}
+
+			wsi->u.http.range.budget = wsi->u.http.range.end -
+						   wsi->u.http.range.start + 1;
+			wsi->u.http.range.inside = 1;
+		}
+#endif
+
+		poss = context->pt_serv_buf_size - n;
+#if defined(LWS_WITH_RANGES)
+		if (wsi->u.http.range.count_ranges) {
+			if (wsi->u.http.range.count_ranges > 1)
+				poss -= 7; /* allow for final boundary */
+			if (poss > wsi->u.http.range.budget)
+				poss = wsi->u.http.range.budget;
+		}
+#endif
 		if (wsi->sending_chunked) {
 			/* we need to drop the chunk size in here */
 			p += 10;
@@ -586,12 +633,15 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
 			poss -= 10 + 128;
 		}
 
-		if (lws_plat_file_read(wsi, wsi->u.http.fd, &amount, p, poss) < 0)
-			return -1; /* caller will close */
+		if (lws_vfs_file_read(wsi->u.http.fop_fd, &amount, p, poss) < 0)
+			goto file_had_it; /* caller will close */
 		
 		//lwsl_notice("amount %ld\n", amount);
 
-		n = (int)amount;
+		if (wsi->sending_chunked)
+			n = (int)amount;
+		else
+			n = (p - pt->serv_buf) + (int)amount;
 		if (n) {
 			lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
 					context->timeout_secs);
@@ -606,35 +656,67 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
 				     wsi->vhost->protocols[(int)wsi->protocol_interpret_idx].callback, wsi,
 				     LWS_CALLBACK_PROCESS_HTML,
 				     wsi->user_space, &args, 0) < 0)
-					return -1;
+					goto file_had_it;
 				n = args.len;
 				p = (unsigned char *)args.p;
+			} else
+				p = pt->serv_buf;
+
+#if defined(LWS_WITH_RANGES)
+			if (wsi->u.http.range.send_ctr + 1 ==
+				wsi->u.http.range.count_ranges && // last range
+			    wsi->u.http.range.count_ranges > 1 && // was 2+ ranges (ie, multipart)
+			    wsi->u.http.range.budget - amount == 0) {// final part
+				n += lws_snprintf((char *)pt->serv_buf + n, 6,
+					"_lws\x0d\x0a"); // append trailing boundary
+				lwsl_debug("added trailing boundary\n");
 			}
-
+#endif
 			m = lws_write(wsi, p, n,
 				      wsi->u.http.filepos == wsi->u.http.filelen ?
 					LWS_WRITE_HTTP_FINAL :
 					LWS_WRITE_HTTP
 				);
 			if (m < 0)
-				return -1;
+				goto file_had_it;
 
 			wsi->u.http.filepos += amount;
+
+#if defined(LWS_WITH_RANGES)
+			if (wsi->u.http.range.count_ranges >= 1) {
+				wsi->u.http.range.budget -= amount;
+				if (wsi->u.http.range.budget == 0) {
+					lwsl_notice("range budget exhausted\n");
+					wsi->u.http.range.inside = 0;
+					wsi->u.http.range.send_ctr++;
+
+					if (lws_ranges_next(&wsi->u.http.range) < 1) {
+						finished = 1;
+						goto all_sent;
+					}
+				}
+			}
+#endif
+
 			if (m != n) {
 				/* adjust for what was not sent */
-				if (lws_plat_file_seek_cur(wsi, wsi->u.http.fd,
+				if (lws_vfs_file_seek_cur(wsi->u.http.fop_fd,
 							   m - n) ==
 							     (unsigned long)-1)
-					return -1;
+					goto file_had_it;
 			}
 		}
 all_sent:
-		if (!wsi->trunc_len &&
-		    wsi->u.http.filepos == wsi->u.http.filelen) {
+		if ((!wsi->trunc_len && wsi->u.http.filepos == wsi->u.http.filelen)
+#if defined(LWS_WITH_RANGES)
+		    || finished)
+#else
+		)
+#endif
+		     {
 			wsi->state = LWSS_HTTP;
 			/* we might be in keepalive, so close it off here */
-			lws_plat_file_close(wsi, wsi->u.http.fd);
-			wsi->u.http.fd = LWS_INVALID_FILE;
+			lws_vfs_file_close(&wsi->u.http.fop_fd);
 			
 			lwsl_debug("file completed\n");
 
@@ -653,6 +735,11 @@ all_sent:
 	lws_callback_on_writable(wsi);
 
 	return 0; /* indicates further processing must be done */
+
+file_had_it:
+	lws_vfs_file_close(&wsi->u.http.fop_fd);
+
+	return -1;
 }
 
 #if LWS_POSIX
@@ -661,10 +748,10 @@ lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len)
 {
 	int n;
 
-	n = recv(wsi->sock, (char *)buf, len, 0);
+	n = recv(wsi->desc.sockfd, (char *)buf, len, 0);
 	if (n >= 0) {
 		if (wsi->vhost)
-			wsi->vhost->rx += n;
+			wsi->vhost->conn_stats.rx += n;
 		lws_restart_ws_ping_pong_timer(wsi);
 		return n;
 	}
@@ -684,7 +771,7 @@ lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)
 	int n = 0;
 
 #if LWS_POSIX
-	n = send(wsi->sock, (char *)buf, len, MSG_NOSIGNAL);
+	n = send(wsi->desc.sockfd, (char *)buf, len, MSG_NOSIGNAL);
 //	lwsl_info("%s: sent len %d result %d", __func__, len, n);
 	if (n >= 0)
 		return n;
@@ -692,8 +779,9 @@ lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)
 	if (LWS_ERRNO == LWS_EAGAIN ||
 	    LWS_ERRNO == LWS_EWOULDBLOCK ||
 	    LWS_ERRNO == LWS_EINTR) {
-		if (LWS_ERRNO == LWS_EWOULDBLOCK)
+		if (LWS_ERRNO == LWS_EWOULDBLOCK) {
 			lws_set_blocking_send(wsi);
+		}
 
 		return LWS_SSL_CAPABLE_MORE_SERVICE;
 	}
@@ -705,7 +793,7 @@ lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)
 	// !!!
 #endif
 
-	lwsl_debug("ERROR writing len %d to skt fd %d err %d / errno %d\n", len, wsi->sock, n, LWS_ERRNO);
+	lwsl_debug("ERROR writing len %d to skt fd %d err %d / errno %d\n", len, wsi->desc.sockfd, n, LWS_ERRNO);
 	return LWS_SSL_CAPABLE_ERROR;
 }
 #endif

+ 80 - 24
EVSE/GPL/libwebsockets-v2.1-stable/lib/parsers.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/parsers.c

@@ -60,6 +60,16 @@ lextable_decode(int pos, char c)
 	}
 }
 
+void
+_lws_header_table_reset(struct allocated_headers *ah)
+{
+	/* init the ah to reflect no headers or data have appeared yet */
+	memset(ah->frag_index, 0, sizeof(ah->frag_index));
+	ah->nfrag = 0;
+	ah->pos = 0;
+	ah->http_response = 0;
+}
+
 // doesn't scrub the ah rxbuffer by default, parent must do if needed
 
 void
@@ -74,10 +84,7 @@ lws_header_table_reset(struct lws *wsi, int autoservice)
 	/* ah also concurs with ownership */
 	assert(ah->wsi == wsi);
 
-	/* init the ah to reflect no headers or data have appeared yet */
-	memset(ah->frag_index, 0, sizeof(ah->frag_index));
-	ah->nfrag = 0;
-	ah->pos = 0;
+	_lws_header_table_reset(ah);
 
 	/* since we will restart the ah, our new headers are not completed */
 	// wsi->hdr_parsing_completed = 0;
@@ -149,7 +156,7 @@ lws_header_table_attach(struct lws *wsi, int autoservice)
 	 * weren't able to deliver it right now
 	 */
 	if (pt->ah_count_in_use == context->max_http_header_pool) {
-		lwsl_notice("%s: adding %p to ah waiting list\n", __func__, wsi);
+		lwsl_info("%s: adding %p to ah waiting list\n", __func__, wsi);
 		wsi->u.hdr.ah_wait_list = pt->ah_wait_list;
 		pt->ah_wait_list = wsi;
 		pt->ah_wait_list_length++;
@@ -534,6 +541,7 @@ lws_parse(struct lws *wsi, unsigned char c)
 		WSI_TOKEN_PUT_URI,
 		WSI_TOKEN_PATCH_URI,
 		WSI_TOKEN_DELETE_URI,
+		WSI_TOKEN_CONNECT,
 	};
 	struct allocated_headers *ah = wsi->u.hdr.ah;
 	struct lws_context *context = wsi->context;
@@ -805,9 +813,16 @@ swallow:
 				}
 			/*
 			 * hm it's an unknown http method from a client in fact,
-			 * treat as dangerous
+			 * it cannot be valid http
 			 */
 			if (m == ARRAY_SIZE(methods)) {
+				/*
+				 * are we set up to accept raw in these cases?
+				 */
+				if (lws_check_opt(wsi->vhost->options,
+					   LWS_SERVER_OPTION_FALLBACK_TO_RAW))
+					return 2; /* transition to raw */
+
 				lwsl_info("Unknown method - dropping\n");
 				goto forbid;
 			}
@@ -940,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;
 		}
@@ -1223,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");
@@ -1398,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
@@ -1411,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) {

+ 68 - 26
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/pollfd.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/pollfd.c

@@ -33,13 +33,33 @@ _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 &&
 	       wsi->position_in_fds_table < pt->fds_count);
 
 	pfd = &pt->fds[wsi->position_in_fds_table];
-	pa->fd = wsi->sock;
+	pa->fd = wsi->desc.sockfd;
 	pa->prev_events = pfd->events;
 	pa->events = pfd->events = (pfd->events & ~_and) | _or;
 
@@ -107,18 +127,38 @@ bail:
 	return ret;
 }
 
+#ifndef LWS_NO_SERVER
+static void
+lws_accept_modulation(struct lws_context_per_thread *pt, int allow)
+{
+// multithread listen seems broken
+#if 0
+	struct lws_vhost *vh = context->vhost_list;
+	struct lws_pollargs pa1;
+
+	while (vh) {
+		if (allow)
+			_lws_change_pollfd(pt->wsi_listening,
+					   0, LWS_POLLIN, &pa1);
+		else
+			_lws_change_pollfd(pt->wsi_listening,
+					   LWS_POLLIN, 0, &pa1);
+		vh = vh->vhost_next;
+	}
+#endif
+}
+#endif
+
 int
 insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)
 {
-	struct lws_pollargs pa = { wsi->sock, LWS_POLLIN, 0 };
+	struct lws_pollargs pa = { wsi->desc.sockfd, LWS_POLLIN, 0 };
 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
 	int ret = 0;
-#ifndef LWS_NO_SERVER
-	struct lws_pollargs pa1;
-#endif
+
 
 	lwsl_debug("%s: %p: tsi=%d, sock=%d, pos-in-fds=%d\n",
-		  __func__, wsi, wsi->tsi, wsi->sock, pt->fds_count);
+		  __func__, wsi, wsi->tsi, wsi->desc.sockfd, pt->fds_count);
 
 	if ((unsigned int)pt->fds_count >= context->fd_limit_per_thread) {
 		lwsl_err("Too many fds (%d vs %d)\n", context->max_fds,
@@ -126,17 +166,17 @@ insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)
 		return 1;
 	}
 
-#if !defined(_WIN32) && !defined(MBED_OPERATORS) && !defined(LWS_WITH_ESP8266)
-	if (wsi->sock >= context->max_fds) {
+#if !defined(_WIN32) && !defined(LWS_WITH_ESP8266)
+	if (wsi->desc.sockfd >= context->max_fds) {
 		lwsl_err("Socket fd %d is too high (%d)\n",
-			 wsi->sock, context->max_fds);
+			 wsi->desc.sockfd, context->max_fds);
 		return 1;
 	}
 #endif
 
 	assert(wsi);
 	assert(wsi->vhost);
-	assert(lws_socket_is_valid(wsi->sock));
+	assert(lws_socket_is_valid(wsi->desc.sockfd));
 
 	if (wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,
 					   wsi->user_space, (void *) &pa, 1))
@@ -152,7 +192,7 @@ insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)
 
 	// lwsl_notice("%s: %p: setting posinfds %d\n", __func__, wsi, wsi->position_in_fds_table);
 
-	pt->fds[wsi->position_in_fds_table].fd = wsi->sock;
+	pt->fds[wsi->position_in_fds_table].fd = wsi->desc.sockfd;
 #if LWS_POSIX
 	pt->fds[wsi->position_in_fds_table].events = LWS_POLLIN;
 #else
@@ -169,7 +209,7 @@ insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)
 #ifndef LWS_NO_SERVER
 	/* if no more room, defeat accepts on this thread */
 	if ((unsigned int)pt->fds_count == context->fd_limit_per_thread - 1)
-		_lws_change_pollfd(pt->wsi_listening, LWS_POLLIN, 0, &pa1);
+		lws_accept_modulation(pt, 0);
 #endif
 	lws_pt_unlock(pt);
 
@@ -184,20 +224,17 @@ int
 remove_wsi_socket_from_fds(struct lws *wsi)
 {
 	struct lws_context *context = wsi->context;
-	struct lws_pollargs pa = { wsi->sock, 0, 0 };
+	struct lws_pollargs pa = { wsi->desc.sockfd, 0, 0 };
 #if !defined(LWS_WITH_ESP8266)
-#ifndef LWS_NO_SERVER
-	struct lws_pollargs pa1;
-#endif
 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
 	struct lws *end_wsi;
 	int v;
 #endif
 	int m, ret = 0;
 
-#if !defined(_WIN32) && !defined(MBED_OPERATORS) && !defined(LWS_WITH_ESP8266)
-	if (wsi->sock > context->max_fds) {
-		lwsl_err("fd %d too high (%d)\n", wsi->sock, context->max_fds);
+#if !defined(_WIN32) && !defined(LWS_WITH_ESP8266)
+	if (wsi->desc.sockfd > context->max_fds) {
+		lwsl_err("fd %d too high (%d)\n", wsi->desc.sockfd, context->max_fds);
 		return 1;
 	}
 #endif
@@ -224,12 +261,14 @@ remove_wsi_socket_from_fds(struct lws *wsi)
 		//lwsl_err("null wsi->prev\n");
 	/* our next should point back to our prev */
 	if (wsi->same_vh_protocol_next) {
-		lwsl_info("have next %p\n");
 		wsi->same_vh_protocol_next->same_vh_protocol_prev =
 				wsi->same_vh_protocol_prev;
 	} //else
 		//lwsl_err("null wsi->next\n");
 
+	wsi->same_vh_protocol_prev = NULL;
+	wsi->same_vh_protocol_next = NULL;
+
 	/* the guy who is to be deleted's slot index in pt->fds */
 	m = wsi->position_in_fds_table;
 	
@@ -240,7 +279,7 @@ remove_wsi_socket_from_fds(struct lws *wsi)
 	lws_pt_lock(pt);
 
 	lwsl_debug("%s: wsi=%p, sock=%d, fds pos=%d, end guy pos=%d, endfd=%d\n",
-		  __func__, wsi, wsi->sock, wsi->position_in_fds_table,
+		  __func__, wsi, wsi->desc.sockfd, wsi->position_in_fds_table,
 		  pt->fds_count, pt->fds[pt->fds_count].fd);
 
 	/* have the last guy take up the now vacant slot */
@@ -259,12 +298,12 @@ remove_wsi_socket_from_fds(struct lws *wsi)
 		end_wsi->position_in_fds_table = m;
 
 	/* deletion guy's lws_lookup entry needs nuking */
-	delete_from_fd(context, wsi->sock);
+	delete_from_fd(context, wsi->desc.sockfd);
 	/* removed wsi has no position any more */
 	wsi->position_in_fds_table = -1;
 
 	/* remove also from external POLL support via protocol 0 */
-	if (lws_socket_is_valid(wsi->sock))
+	if (lws_socket_is_valid(wsi->desc.sockfd))
 		if (wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_DEL_POLL_FD,
 						   wsi->user_space, (void *) &pa, 0))
 			ret = -1;
@@ -272,7 +311,7 @@ remove_wsi_socket_from_fds(struct lws *wsi)
 	if (!context->being_destroyed)
 		/* if this made some room, accept connects on this thread */
 		if ((unsigned int)pt->fds_count < context->fd_limit_per_thread - 1)
-			_lws_change_pollfd(pt->wsi_listening, 0, LWS_POLLIN, &pa1);
+			lws_accept_modulation(pt, 1);
 #endif
 	lws_pt_unlock(pt);
 
@@ -377,7 +416,7 @@ network_sock:
 		return 1;
 
 	if (wsi->position_in_fds_table < 0) {
-		lwsl_err("%s: failed to find socket %d\n", __func__, wsi->sock);
+		lwsl_err("%s: failed to find socket %d\n", __func__, wsi->desc.sockfd);
 		return -1;
 	}
 
@@ -395,7 +434,10 @@ lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost,
 
 	if (protocol < vhost->protocols ||
 	    protocol >= (vhost->protocols + vhost->count_protocols)) {
-		lwsl_err("%s: protocol is not from vhost\n", __func__);
+
+		lwsl_err("%s: protocol %p is not from vhost %p (%p - %p)\n",
+			__func__, protocol, vhost->protocols, vhost,
+			(vhost->protocols + vhost->count_protocols));
 
 		return -1;
 	}

+ 165 - 81
EVSE/GPL/libwebsockets-v2.1-stable/lib/private-libwebsockets.h → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/private-libwebsockets.h

@@ -38,6 +38,12 @@
 #include <ctype.h>
 #include <limits.h>
 #include <stdarg.h>
+
+#if defined(LWS_WITH_ESP32)
+#define MSG_NOSIGNAL 0
+#define SOMAXCONN 3
+#endif
+
 #if defined(LWS_WITH_ESP8266)
 #include <user_interface.h>
 #define assert(n)
@@ -132,16 +138,15 @@ char *ets_strchr(const char *s, int c);
 #define __func__ __FUNCTION__
 #endif
 
-#if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(_WIN32_WCE)
-#define vsnprintf _vsnprintf
-#else
 #ifdef LWS_HAVE__VSNPRINTF
 #define vsnprintf _vsnprintf
 #endif
-#endif
 
-#ifdef LWS_HAVE__SNPRINTF
-#define lws_snprintf _snprintf
+/* we don't have an implementation for this on windows... */
+int kill(int pid, int sig);
+int fork(void);
+#ifndef SIGINT
+#define SIGINT 2
 #endif
 
 #else /* not windows --> */
@@ -150,7 +155,7 @@ char *ets_strchr(const char *s, int c);
 #include <strings.h>
 #include <unistd.h>
 #include <sys/types.h>
-#ifndef MBED_OPERATORS
+
 #ifndef __cplusplus
 #include <errno.h>
 #endif
@@ -161,6 +166,9 @@ char *ets_strchr(const char *s, int c);
 #define vsnprintf ets_vsnprintf
 #define snprintf ets_snprintf
 #define sprintf ets_sprintf
+
+int kill(int pid, int sig);
+
 #else
 #include <sys/socket.h>
 #endif
@@ -171,7 +179,7 @@ char *ets_strchr(const char *s, int c);
 #if defined(LWS_BUILTIN_GETIFADDRS)
  #include <getifaddrs.h>
 #else
- #if !defined(LWS_WITH_ESP8266)
+ #if !defined(LWS_WITH_ESP8266) && !defined(LWS_WITH_ESP32)
  #include <ifaddrs.h>
  #endif
 #endif
@@ -181,12 +189,12 @@ char *ets_strchr(const char *s, int c);
 #elif defined (__sun)
 #include <syslog.h>
 #else
-#if !defined(LWS_WITH_ESP8266)
+#if !defined(LWS_WITH_ESP8266)  && !defined(LWS_WITH_ESP32)
 #include <sys/syslog.h>
 #endif
 #endif
 #include <netdb.h>
-#if !defined(LWS_WITH_ESP8266)
+#if !defined(LWS_WITH_ESP8266) && !defined(LWS_WITH_ESP32)
 #include <sys/mman.h>
 #include <sys/un.h>
 #include <netinet/in.h>
@@ -201,8 +209,6 @@ char *ets_strchr(const char *s, int c);
 #include <uv.h>
 #endif
 
-#endif /* MBED */
-
 #ifndef LWS_NO_FORK
 #ifdef LWS_HAVE_SYS_PRCTL_H
 #include <sys/prctl.h>
@@ -221,7 +227,7 @@ char *ets_strchr(const char *s, int c);
 
 #define lws_set_blocking_send(wsi)
 
-#if defined(MBED_OPERATORS) || defined(LWS_WITH_ESP8266)
+#if defined(LWS_WITH_ESP8266)
 #define lws_socket_is_valid(x) ((x) != NULL)
 #define LWS_SOCK_INVALID (NULL)
 struct lws;
@@ -252,26 +258,11 @@ lws_plat_get_peer_simple(struct lws *wsi, char *name, int namelen);
 #else
 #include <wolfssl/openssl/ssl.h>
 #include <wolfssl/error-ssl.h>
+#define OPENSSL_NO_TLSEXT
 #endif /* not USE_OLD_CYASSL */
 #else
-#if defined(LWS_USE_POLARSSL)
-#include <polarssl/ssl.h>
-#include <polarssl/error.h>
-#include <polarssl/md5.h>
-#include <polarssl/sha1.h>
-#include <polarssl/ecdh.h>
-#define SSL_ERROR_WANT_READ POLARSSL_ERR_NET_WANT_READ
-#define SSL_ERROR_WANT_WRITE POLARSSL_ERR_NET_WANT_WRITE
-#define OPENSSL_VERSION_NUMBER  0x10002000L
-#else
-#if defined(LWS_USE_MBEDTLS)
-#include <mbedtls/ssl.h>
-#include <mbedtls/error.h>
-#include <mbedtls/md5.h>
-#include <mbedtls/sha1.h>
-#include <mbedtls/ecdh.h>
-#else
 #include <openssl/ssl.h>
+#if !defined(LWS_WITH_ESP32)
 #include <openssl/evp.h>
 #include <openssl/err.h>
 #include <openssl/md5.h>
@@ -280,8 +271,14 @@ lws_plat_get_peer_simple(struct lws *wsi, char *name, int namelen);
 #include <openssl/ecdh.h>
 #endif
 #include <openssl/x509v3.h>
-#endif /* not USE_MBEDTLS */
-#endif /* not USE_POLARSSL */
+#endif
+#if (OPENSSL_VERSION_NUMBER < 0x0009080afL)
+/* later openssl defines this to negate the presence of tlsext... but it was only
+ * introduced at 0.9.8j.  Earlier versions don't know it exists so don't
+ * define it... making it look like the feature exists...
+ */
+#define OPENSSL_NO_TLSEXT
+#endif
 #endif /* not USE_WOLFSSL */
 #endif
 
@@ -291,18 +288,8 @@ lws_plat_get_peer_simple(struct lws *wsi, char *name, int namelen);
 static inline int compatible_close(int fd) { return close(fd); }
 #endif
 
-#if defined(MBED_OPERATORS)
-#undef compatible_close
-#define compatible_close(fd) mbed3_delete_tcp_stream_socket(fd)
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN    4321  /* to show byte order (taken from gcc) */
-#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-#ifndef BYTE_ORDER
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif
+#if defined(WIN32) || defined(_WIN32)
+#include <gettimeofday.h>
 #endif
 
 #if defined(LWS_WITH_ESP8266)
@@ -380,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
@@ -550,10 +549,15 @@ enum connection_mode {
 	/* transient, ssl delay hiding */
 	LWSCM_SSL_ACK_PENDING,
 	LWSCM_SSL_INIT,
+	/* as above, but complete into LWSCM_RAW */
+	LWSCM_SSL_ACK_PENDING_RAW,
+	LWSCM_SSL_INIT_RAW,
 
 	/* special internal types */
 	LWSCM_SERVER_LISTENER,
 	LWSCM_CGI, /* stdin, stdout, stderr for another cgi master wsi */
+	LWSCM_RAW, /* raw with bulk handling */
+	LWSCM_RAW_FILEDESC, /* raw without bulk handling */
 
 	/* HTTP Client related */
 	LWSCM_HTTP_CLIENT = LWSCM_FLAG_IMPLIES_CALLBACK_CLOSED_CLIENT_HTTP,
@@ -648,10 +652,13 @@ struct allocated_headers {
 	 */
 	unsigned char frag_index[WSI_TOKEN_COUNT];
 	unsigned char rx[2048];
+
 	unsigned int rxpos;
 	unsigned int rxlen;
 	unsigned int pos;
 
+	unsigned int http_response;
+
 #ifndef LWS_NO_CLIENT
 	char initial_handshake_hash_base64[30];
 #endif
@@ -689,9 +696,6 @@ struct lws_context_per_thread {
 #ifdef LWS_OPENSSL_SUPPORT
 	struct lws *pending_read_list; /* linked list */
 #endif
-#ifndef LWS_NO_SERVER
-	struct lws *wsi_listening;
-#endif
 #if defined(LWS_USE_LIBEV)
 	struct ev_loop *io_loop_ev;
 #endif
@@ -728,6 +732,14 @@ struct lws_context_per_thread {
 	unsigned char lock_depth;
 };
 
+struct lws_conn_stats {
+	unsigned long long rx, tx;
+	unsigned long conn, trans, ws_upg, http2_upg, rejected;
+};
+
+void
+lws_sum_stats(const struct lws_context *ctx, struct lws_conn_stats *cs);
+
 /*
  * virtual host -related context information
  *   vhostwide SSL context
@@ -755,6 +767,7 @@ struct lws_vhost {
 	/* listen sockets need a place to hang their hat */
 	esp_tcp tcp;
 #endif
+	struct lws_conn_stats conn_stats;
 	struct lws_context *context;
 	struct lws_vhost *vhost_next;
 	const struct lws_http_mount *mount_list;
@@ -773,8 +786,6 @@ struct lws_vhost {
 #ifndef LWS_NO_EXTENSIONS
 	const struct lws_extension *extensions;
 #endif
-	unsigned long long rx, tx;
-	unsigned long conn, trans, ws_upgrades, http2_upgrades;
 
 	int listen_port;
 	unsigned int http_proxy_port;
@@ -794,7 +805,10 @@ struct lws_vhost {
 	unsigned int user_supplied_ssl_ctx:1;
 #endif
 
+	unsigned int created_vhost_protocols:1;
+
 	unsigned char default_protocol_index;
+	unsigned char raw_protocol_index;
 };
 
 /*
@@ -808,8 +822,13 @@ struct lws_context {
 	time_t last_timeout_check_s;
 	time_t last_ws_ping_pong_check_s;
 	time_t time_up;
-	struct lws_plat_file_ops fops;
+	const struct lws_plat_file_ops *fops;
+	struct lws_plat_file_ops fops_platform;
+#if defined(LWS_WITH_ZIP_FOPS)
+	struct lws_plat_file_ops fops_zip;
+#endif
 	struct lws_context_per_thread pt[LWS_MAX_SMP];
+	struct lws_conn_stats conn_stats;
 #ifdef _WIN32
 /* different implementation between unix and windows */
 	struct lws_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];
@@ -825,9 +844,13 @@ struct lws_context {
 #endif
 	struct lws_vhost *vhost_list;
 	struct lws_plugin *plugin_list;
+
+	void *external_baggage_free_on_destroy;
 	const struct lws_token_limits *token_limits;
 	void *user_space;
 	const char *server_string;
+	const struct lws_protocol_vhost_options *reject_service_keywords;
+	lws_reload_func deprecation_cb;
 
 #if defined(LWS_USE_LIBEV)
 	lws_ev_signal_cb_t * lws_ev_sigint_cb;
@@ -868,6 +891,12 @@ struct lws_context {
 	unsigned int pt_serv_buf_size;
 	int max_http_header_data;
 
+	unsigned int deprecated:1;
+	unsigned int being_destroyed:1;
+	unsigned int being_destroyed1:1;
+	unsigned int requested_kill:1;
+	unsigned int protocol_init_done:1;
+
 	/*
 	 * set to the Thread ID that's doing the service loop just before entry
 	 * to poll indicates service thread likely idling in poll()
@@ -883,10 +912,8 @@ struct lws_context {
 	short plugin_extension_count;
 	short server_string_len;
 	unsigned short ws_ping_pong_interval;
-
-	unsigned int being_destroyed:1;
-	unsigned int requested_kill:1;
-	unsigned int protocol_init_done:1;
+	unsigned short deprecation_pending_listen_close_count;
+	uint8_t max_fi;
 };
 
 #define lws_get_context_protocol(ctx, x) ctx->vhost_list->protocols[x]
@@ -921,7 +948,7 @@ enum {
 
 #if defined(LWS_USE_LIBEV)
 LWS_EXTERN void
-lws_libev_accept(struct lws *new_wsi, lws_sockfd_type accept_fd);
+lws_libev_accept(struct lws *new_wsi, lws_sock_file_fd_type desc);
 LWS_EXTERN void
 lws_libev_io(struct lws *wsi, int flags);
 LWS_EXTERN int
@@ -939,7 +966,7 @@ LWS_EXTERN void lws_feature_status_libev(struct lws_context_creation_info *info)
 #define lws_libev_run(_a, _b) ((void) 0)
 #define lws_libev_destroyloop(_a, _b) ((void) 0)
 #define LWS_LIBEV_ENABLED(context) (0)
-#if LWS_POSIX
+#if LWS_POSIX && !defined(LWS_WITH_ESP32)
 #define lws_feature_status_libev(_a) \
 			lwsl_notice("libev support not compiled in\n")
 #else
@@ -949,7 +976,7 @@ LWS_EXTERN void lws_feature_status_libev(struct lws_context_creation_info *info)
 
 #if defined(LWS_USE_LIBUV)
 LWS_EXTERN void
-lws_libuv_accept(struct lws *new_wsi, lws_sockfd_type accept_fd);
+lws_libuv_accept(struct lws *new_wsi, lws_sock_file_fd_type desc);
 LWS_EXTERN void
 lws_libuv_io(struct lws *wsi, int flags);
 LWS_EXTERN int
@@ -958,6 +985,8 @@ LWS_EXTERN void
 lws_libuv_run(const struct lws_context *context, int tsi);
 LWS_EXTERN void
 lws_libuv_destroyloop(struct lws_context *context, int tsi);
+LWS_EXTERN int
+lws_uv_initvhost(struct lws_vhost* vh, struct lws*);
 #define LWS_LIBUV_ENABLED(context) lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV)
 LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info);
 #else
@@ -967,7 +996,7 @@ LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info)
 #define lws_libuv_run(_a, _b) ((void) 0)
 #define lws_libuv_destroyloop(_a, _b) ((void) 0)
 #define LWS_LIBUV_ENABLED(context) (0)
-#if LWS_POSIX
+#if LWS_POSIX && !defined(LWS_WITH_ESP32)
 #define lws_feature_status_libuv(_a) \
 			lwsl_notice("libuv support not compiled in\n")
 #else
@@ -1019,7 +1048,7 @@ enum uri_esc_states {
 #ifndef LWS_NO_CLIENT
 struct client_info_stash {
 	char address[256];
-	char path[1024];
+	char path[4096];
 	char host[256];
 	char origin[256];
 	char protocol[256];
@@ -1040,15 +1069,39 @@ struct _lws_header_related {
 	enum uri_esc_states ues;
 	short lextable_pos;
 	unsigned int current_token_limit;
-#ifndef LWS_NO_CLIENT
-	unsigned short c_port;
-#endif
+
 	char esc_stash;
 	char post_literal_equal;
 	unsigned char parser_state; /* enum lws_token_indexes */
-	char redirects;
 };
 
+#if defined(LWS_WITH_RANGES)
+enum range_states {
+	LWSRS_NO_ACTIVE_RANGE,
+	LWSRS_BYTES_EQ,
+	LWSRS_FIRST,
+	LWSRS_STARTING,
+	LWSRS_ENDING,
+	LWSRS_COMPLETED,
+	LWSRS_SYNTAX,
+};
+
+struct lws_range_parsing {
+	unsigned long long start, end, extent, agg, budget;
+	const char buf[128];
+	int pos;
+	enum range_states state;
+	char start_valid, end_valid, ctr, count_ranges, did_try, inside, send_ctr;
+};
+
+int
+lws_ranges_init(struct lws *wsi, struct lws_range_parsing *rp, unsigned long long extent);
+int
+lws_ranges_next(struct lws_range_parsing *rp);
+void
+lws_ranges_reset(struct lws_range_parsing *rp);
+#endif
+
 struct _lws_http_mode_related {
 	/* MUST be first in struct */
 	struct allocated_headers *ah; /* mirroring  _lws_header_related */
@@ -1059,9 +1112,14 @@ struct _lws_http_mode_related {
 #endif
 	unsigned int preamble_rx_len;
 	struct lws *new_wsi_list;
-	unsigned long filepos;
-	unsigned long filelen;
-	lws_filefd_type fd;
+	lws_filepos_t filepos;
+	lws_filepos_t filelen;
+	lws_fop_fd_t fop_fd;
+
+#if defined(LWS_WITH_RANGES)
+	struct lws_range_parsing range;
+	char multipart_content_type[64];
+#endif
 
 	enum http_version request_version;
 	enum http_connection_type connection_type;
@@ -1274,6 +1332,8 @@ struct lws_cgi {
 	int pid;
 
 	unsigned int being_closed:1;
+
+	unsigned char chunked_grace;
 };
 #endif
 
@@ -1358,9 +1418,7 @@ struct lws {
 #endif
 #ifdef LWS_OPENSSL_SUPPORT
 	SSL *ssl;
-#if !defined(LWS_USE_POLARSSL) && !defined(LWS_USE_MBEDTLS)
 	BIO *client_bio;
-#endif
 	struct lws *pending_read_list_prev, *pending_read_list_next;
 #endif
 #ifdef LWS_WITH_HTTP_PROXY
@@ -1370,8 +1428,7 @@ struct lws {
 	unsigned long action_start;
 	unsigned long latency_start;
 #endif
-	/* pointer / int */
-	lws_sockfd_type sock;
+	lws_sock_file_fd_type desc; /* .filefd / .sockfd */
 
 	/* ints */
 	int position_in_fds_table;
@@ -1400,6 +1457,7 @@ struct lws {
 	unsigned int sending_chunked:1;
 	unsigned int already_did_cce:1;
 	unsigned int told_user_closed:1;
+
 #if defined(LWS_WITH_ESP8266)
 	unsigned int pending_send_completion:3;
 	unsigned int close_is_pending_send_completion:1;
@@ -1420,8 +1478,7 @@ struct lws {
 	unsigned int extension_data_pending:1;
 #endif
 #ifdef LWS_OPENSSL_SUPPORT
-	unsigned int use_ssl:3;
-	unsigned int upgraded:1;
+	unsigned int use_ssl:4;
 #endif
 #ifdef _WIN32
 	unsigned int sock_send_blocking:1;
@@ -1430,6 +1487,14 @@ 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
+
 	/* chars */
 #ifndef LWS_NO_EXTENSIONS
 	unsigned char count_act_ext;
@@ -1444,6 +1509,7 @@ struct lws {
 	char pps; /* enum lws_pending_protocol_send */
 	char tsi; /* thread service index we belong to */
 	char protocol_interpret_idx;
+	char redirects;
 #ifdef LWS_WITH_CGI
 	char cgi_channel; /* which of stdin/out/err */
 	char hdr_state;
@@ -1459,7 +1525,7 @@ struct lws {
 LWS_EXTERN int log_level;
 
 LWS_EXTERN int
-lws_socket_bind(struct lws_vhost *vhost, int sockfd, int port,
+lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
 		const char *iface);
 
 LWS_EXTERN void
@@ -1508,7 +1574,7 @@ lws_b64_selftest(void);
 LWS_EXTERN int
 lws_service_flag_pending(struct lws_context *context, int tsi);
 
-#if defined(_WIN32) || defined(MBED_OPERATORS) || defined(LWS_WITH_ESP8266)
+#if defined(_WIN32) || defined(LWS_WITH_ESP8266)
 LWS_EXTERN struct lws *
 wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd);
 
@@ -1519,7 +1585,7 @@ LWS_EXTERN int
 delete_from_fd(struct lws_context *context, lws_sockfd_type fd);
 #else
 #define wsi_from_fd(A,B)  A->lws_lookup[B]
-#define insert_wsi(A,B)   assert(A->lws_lookup[B->sock] == 0); A->lws_lookup[B->sock]=B
+#define insert_wsi(A,B)   assert(A->lws_lookup[B->desc.sockfd] == 0); A->lws_lookup[B->desc.sockfd]=B
 #define delete_from_fd(A,B) A->lws_lookup[B]=0
 #endif
 
@@ -1533,11 +1599,14 @@ lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len);
 LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_service_timeout_check(struct lws *wsi, unsigned int sec);
 
+LWS_EXTERN void
+lws_remove_from_timeout_list(struct lws *wsi);
+
 LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
 lws_client_connect_2(struct lws *wsi);
 
 LWS_VISIBLE struct lws * LWS_WARN_UNUSED_RESULT
-lws_client_reset(struct lws *wsi, int ssl, const char *address, int port,
+lws_client_reset(struct lws **wsi, int ssl, const char *address, int port,
 		 const char *path, const char *host);
 
 LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
@@ -1649,6 +1718,8 @@ lws_header_table_detach(struct lws *wsi, int autoservice);
 
 LWS_EXTERN void
 lws_header_table_reset(struct lws *wsi, int autoservice);
+void
+_lws_header_table_reset(struct allocated_headers *ah);
 
 LWS_EXTERN char * LWS_WARN_UNUSED_RESULT
 lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h);
@@ -1686,7 +1757,7 @@ LWS_EXTERN int get_daemonize_pid();
 #define get_daemonize_pid() (0)
 #endif
 
-#if !defined(MBED_OPERATORS) && !defined(LWS_WITH_ESP8266)
+#if !defined(LWS_WITH_ESP8266)
 LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 interface_to_sa(struct lws_vhost *vh, const char *ifname,
 		struct sockaddr_in *addr, size_t addrlen);
@@ -1862,12 +1933,9 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
 			  struct lws_pollfd *pollfd);
 LWS_EXTERN int
 lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len);
-LWS_EXTERN int
-_lws_server_listen_accept_flow_control(struct lws *twsi, int on);
 #else
 #define lws_server_socket_service(_a, _b, _c) (0)
 #define lws_handshake_server(_a, _b, _c) (0)
-#define _lws_server_listen_accept_flow_control(a, b) (0)
 #endif
 
 #ifdef LWS_WITH_ACCESS_LOG
@@ -1898,9 +1966,19 @@ lws_realloc(void *ptr, size_t size);
 LWS_EXTERN void * LWS_WARN_UNUSED_RESULT
 lws_zalloc(size_t size);
 
+#ifdef LWS_PLAT_OPTEE
+void *lws_malloc(size_t size);
+void lws_free(void *p);
+#define lws_free_set_NULL(P)    do { lws_free(P); (P) = NULL; } while(0)
+#else
 #define lws_malloc(S)	lws_realloc(NULL, S)
 #define lws_free(P)	lws_realloc(P, 0)
 #define lws_free_set_NULL(P)	do { lws_realloc(P, 0); (P) = NULL; } while(0)
+#endif
+
+const struct lws_plat_file_ops *
+lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path,
+		    const char **vpath);
 
 /* lws_plat_ */
 LWS_EXTERN void
@@ -1915,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
@@ -1926,7 +2008,7 @@ lws_poll_listen_fd(struct lws_pollfd *fd);
 LWS_EXTERN int
 lws_plat_service(struct lws_context *context, int timeout_ms);
 LWS_EXTERN LWS_VISIBLE int
-lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
+_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
 LWS_EXTERN int
 lws_plat_init(struct lws_context *context,
 	      struct lws_context_creation_info *info);
@@ -1939,6 +2021,8 @@ lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt);
 
 LWS_EXTERN int LWS_WARN_UNUSED_RESULT
 lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len);
+LWS_EXTERN int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf,
+		                lws_filepos_t *amount);
 
 #ifdef __cplusplus
 };

+ 211 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ranges.c

@@ -0,0 +1,211 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * RFC7233 ranges parser
+ *
+ * Copyright (C) 2016 Andy Green <andy@warmcat.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  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.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "private-libwebsockets.h"
+
+/*
+ * RFC7233 examples
+ *
+ * o  The first 500 bytes (byte offsets 0-499, inclusive):
+ *
+ *      bytes=0-499
+ *
+ * o  The second 500 bytes (byte offsets 500-999, inclusive):
+ *
+ *      bytes=500-999
+ *
+ * o  The final 500 bytes (byte offsets 9500-9999, inclusive):
+ *
+ *      bytes=-500
+ *
+ * Or:
+ *
+ *      bytes=9500-
+ *
+ * o  The first and last bytes only (bytes 0 and 9999):
+ *
+ *      bytes=0-0,-1
+ *
+ * o  Other valid (but not canonical) specifications of the second 500
+ *    bytes (byte offsets 500-999, inclusive):
+ *
+ *      bytes=500-600,601-999
+ *      bytes=500-700,601-999
+ */
+
+/*
+ * returns 1 if the range struct represents a usable range
+ *   if no ranges header, you get one of these for the whole
+ *   file.  Otherwise you get one for each valid range in the
+ *   header.
+ *
+ * returns 0 if no further valid range forthcoming; rp->state
+ *   may be LWSRS_SYNTAX or LWSRS_COMPLETED
+ */
+
+int
+lws_ranges_next(struct lws_range_parsing *rp)
+{
+	static const char * const beq = "bytes=";
+	char c;
+
+	while (1) {
+
+		c = rp->buf[rp->pos];
+
+		switch (rp->state) {
+		case LWSRS_SYNTAX:
+		case LWSRS_COMPLETED:
+			return 0;
+
+		case LWSRS_NO_ACTIVE_RANGE:
+			rp->state = LWSRS_COMPLETED;
+			return 0;
+
+		case LWSRS_BYTES_EQ: // looking for "bytes="
+			if (c != beq[rp->pos]) {
+				rp->state = LWSRS_SYNTAX;
+				return -1;
+			}
+			if (rp->pos == 5)
+				rp->state = LWSRS_FIRST;
+			break;
+
+		case LWSRS_FIRST:
+			rp->start = 0;
+			rp->end = 0;
+			rp->start_valid = 0;
+			rp->end_valid = 0;
+
+			rp->state = LWSRS_STARTING;
+
+			// fallthru
+
+		case LWSRS_STARTING:
+			if (c == '-') {
+				rp->state = LWSRS_ENDING;
+				break;
+			}
+
+			if (!(c >= '0' && c <= '9')) {
+				rp->state = LWSRS_SYNTAX;
+				return 0;
+			}
+			rp->start = (rp->start * 10) + (c - '0');
+			rp->start_valid = 1;
+			break;
+
+		case LWSRS_ENDING:
+			if (c == ',' || c == '\0') {
+				rp->state = LWSRS_FIRST;
+				if (c == ',')
+					rp->pos++;
+
+				/* by the end of this, start and end are always valid if the range still is */
+
+				if (!rp->start_valid) { /* eg, -500 */
+					if (rp->end > rp->extent)
+						rp->end = rp->extent;
+
+					rp->start = rp->extent - rp->end;
+					rp->end = rp->extent - 1;
+				} else
+					if (!rp->end_valid)
+						rp->end = rp->extent - 1;
+
+				rp->did_try = 1;
+
+				/* end must be >= start or ignore it */
+				if (rp->end < rp->start) {
+					if (c == ',')
+						break;
+					rp->state = LWSRS_COMPLETED;
+					return 0;
+				}
+
+				return 1; /* issue range */
+			}
+
+			if (!(c >= '0' && c <= '9')) {
+				rp->state = LWSRS_SYNTAX;
+				return 0;
+			}
+			rp->end = (rp->end * 10) + (c - '0');
+			rp->end_valid = 1;
+			break;
+		}
+
+		rp->pos++;
+	}
+}
+
+void
+lws_ranges_reset(struct lws_range_parsing *rp)
+{
+	rp->pos = 0;
+	rp->ctr = 0;
+	rp->start = 0;
+	rp->end = 0;
+	rp->start_valid = 0;
+	rp->end_valid = 0;
+	rp->state = LWSRS_BYTES_EQ;
+}
+
+/*
+ * returns count of valid ranges
+ */
+int
+lws_ranges_init(struct lws *wsi, struct lws_range_parsing *rp,
+		unsigned long long extent)
+{
+	rp->agg = 0;
+	rp->send_ctr = 0;
+	rp->inside = 0;
+	rp->count_ranges = 0;
+	rp->did_try = 0;
+	lws_ranges_reset(rp);
+	rp->state = LWSRS_COMPLETED;
+
+	rp->extent = extent;
+
+	if (lws_hdr_copy(wsi, (char *)rp->buf, sizeof(rp->buf),
+			 WSI_TOKEN_HTTP_RANGE) <= 0)
+		return 0;
+
+	rp->state = LWSRS_BYTES_EQ;
+
+	while (lws_ranges_next(rp)) {
+		rp->count_ranges++;
+		rp->agg += rp->end - rp->start + 1;
+	}
+
+	lwsl_debug("%s: count %d\n", __func__, rp->count_ranges);
+	lws_ranges_reset(rp);
+
+	if (rp->did_try && !rp->count_ranges)
+		return -1; /* "not satisfiable */
+
+	lws_ranges_next(rp);
+
+	return rp->count_ranges;
+}

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/rewrite.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/rewrite.c


+ 216 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/romfs.c

@@ -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 - 0
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/romfs.h

@@ -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);
+

+ 102 - 33
EVSE/GPL/libwebsockets-v2.1-stable/lib/server-handshake.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/server-handshake.c

@@ -22,18 +22,20 @@
 #include "private-libwebsockets.h"
 
 #define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); }
+
 #ifndef LWS_NO_EXTENSIONS
-LWS_VISIBLE int
-lws_extension_server_handshake(struct lws *wsi, char **p)
+static int
+lws_extension_server_handshake(struct lws *wsi, char **p, int budget)
 {
 	struct lws_context *context = wsi->context;
 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
+	char ext_name[64], *args, *end = (*p) + budget - 1;
+	const struct lws_ext_options *opts, *po;
 	const struct lws_extension *ext;
-	char ext_name[128];
+	struct lws_ext_option_arg oa;
+	int n, m, more = 1;
 	int ext_count = 0;
-	int more = 1;
 	char ignore;
-	int n, m;
 	char *c;
 
 	/*
@@ -55,13 +57,29 @@ lws_extension_server_handshake(struct lws *wsi, char **p)
 	c = (char *)pt->serv_buf;
 	lwsl_parser("WSI_TOKEN_EXTENSIONS = '%s'\n", c);
 	wsi->count_act_ext = 0;
-	n = 0;
 	ignore = 0;
+	n = 0;
+	args = NULL;
+
+	/*
+	 * We may get a simple request
+	 *
+	 * Sec-WebSocket-Extensions: permessage-deflate
+	 *
+	 * or an elaborated one with requested options
+	 *
+	 * Sec-WebSocket-Extensions: permessage-deflate; \
+	 *			     server_no_context_takeover; \
+	 *			     client_no_context_takeover
+	 */
+
 	while (more) {
 
 		if (*c && (*c != ',' && *c != '\t')) {
-			if (*c == ';')
+			if (*c == ';') {
 				ignore = 1;
+				args = c + 1;
+			}
 			if (ignore || *c == ' ') {
 				c++;
 				continue;
@@ -82,6 +100,9 @@ lws_extension_server_handshake(struct lws *wsi, char **p)
 				continue;
 		}
 
+		while (args && *args && *args == ' ')
+			args++;
+
 		/* check a client's extension against our support */
 
 		ext = wsi->vhost->extensions;
@@ -92,17 +113,18 @@ lws_extension_server_handshake(struct lws *wsi, char **p)
 				ext++;
 				continue;
 			}
-#if 0
-			m = ext->callback(lws_get_context(wsi), ext, wsi,
-					  LWS_EXT_CB_ARGS_VALIDATE,
-					  NULL, start + n, 0);
-			if (m) {
-				ext++;
-				continue;
-			}
-#endif
+
 			/*
 			 * oh, we do support this one he asked for... but let's
+			 * confirm he only gave it once
+			 */
+			for (m = 0; m < wsi->count_act_ext; m++)
+				if (wsi->active_extensions[m] == ext) {
+					lwsl_info("extension mentioned twice\n");
+					return 1; /* shenanigans */
+				}
+
+			/*
 			 * ask user code if it's OK to apply it on this
 			 * particular connection + protocol
 			 */
@@ -115,7 +137,6 @@ lws_extension_server_handshake(struct lws *wsi, char **p)
 			 * the extension, it's what we get if the callback is
 			 * unhandled
 			 */
-
 			if (m) {
 				ext++;
 				continue;
@@ -132,28 +153,72 @@ lws_extension_server_handshake(struct lws *wsi, char **p)
 			/* allow him to construct his context */
 
 			if (ext->callback(lws_get_context(wsi), ext, wsi,
-				      LWS_EXT_CB_CONSTRUCT,
-				      (void *)&wsi->act_ext_user[wsi->count_act_ext],
-				      NULL, 0)) {
-				lwsl_notice("ext %s failed construction\n", ext_name);
+					  LWS_EXT_CB_CONSTRUCT,
+					  (void *)&wsi->act_ext_user[
+					                    wsi->count_act_ext],
+					  &opts, 0)) {
+				lwsl_notice("ext %s failed construction\n",
+					    ext_name);
 				ext_count--;
 				ext++;
+
 				continue;
 			}
 
 			if (ext_count > 1)
 				*(*p)++ = ',';
 			else
-				LWS_CPYAPP(*p, "\x0d\x0aSec-WebSocket-Extensions: ");
-			*p += sprintf(*p, "%s", ext_name);
+				LWS_CPYAPP(*p,
+					  "\x0d\x0aSec-WebSocket-Extensions: ");
+			*p += lws_snprintf(*p, (end - *p), "%s", ext_name);
+
+			/*
+			 *  go through the options trying to apply the
+			 * recognized ones
+			 */
+
+			lwsl_debug("ext args %s", args);
+
+			while (args && *args && *args != ',') {
+				while (*args == ' ')
+					args++;
+				po = opts;
+				while (po->name) {
+					lwsl_debug("'%s' '%s'\n", po->name, args);
+					/* only support arg-less options... */
+					if (po->type == EXTARG_NONE &&
+					    !strncmp(args, po->name,
+							    strlen(po->name))) {
+						oa.option_name = NULL;
+						oa.option_index = po - opts;
+						oa.start = NULL;
+						lwsl_debug("setting %s\n", po->name);
+						if (!ext->callback(
+								lws_get_context(wsi), ext, wsi,
+								  LWS_EXT_CB_OPTION_SET,
+								  wsi->act_ext_user[
+								         wsi->count_act_ext],
+								  &oa, (end - *p))) {
+
+							*p += lws_snprintf(*p, (end - *p), "; %s", po->name);
+							lwsl_debug("adding option %s\n", po->name);
+						}
+					}
+					po++;
+				}
+				while (*args && *args != ',' && *args != ';')
+					args++;
+			}
 
 			wsi->count_act_ext++;
-			lwsl_parser("count_act_ext <- %d\n", wsi->count_act_ext);
+			lwsl_parser("count_act_ext <- %d\n",
+				    wsi->count_act_ext);
 
 			ext++;
 		}
 
 		n = 0;
+		args = NULL;
 	}
 
 	return 0;
@@ -190,8 +255,8 @@ handshake_0405(struct lws_context *context, struct lws *wsi)
 
 	lws_SHA1(pt->serv_buf, n, hash);
 
-	accept_len = lws_b64_encode_string((char *)hash, 20, (char *)pt->serv_buf,
-			context->pt_serv_buf_size);
+	accept_len = lws_b64_encode_string((char *)hash, 20,
+			(char *)pt->serv_buf, context->pt_serv_buf_size);
 	if (accept_len < 0) {
 		lwsl_warn("Base64 encoded hash too long\n");
 		goto bail;
@@ -214,20 +279,24 @@ handshake_0405(struct lws_context *context, struct lws *wsi)
 	strcpy(p, (char *)pt->serv_buf);
 	p += accept_len;
 
-	if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL)) {
+	/* we can only return the protocol header if:
+	 *  - one came in, and ... */
+	if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL) &&
+	    /*  - it is not an empty string */
+	    wsi->protocol->name &&
+	    wsi->protocol->name[0]) {
 		LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: ");
-		n = lws_hdr_copy(wsi, p, 128, WSI_TOKEN_PROTOCOL);
-		if (n < 0)
-			goto bail;
-		p += n;
+		p += lws_snprintf(p, 128, "%s", wsi->protocol->name);
 	}
 
 #ifndef LWS_NO_EXTENSIONS
 	/*
 	 * Figure out which extensions the client has that we want to
-	 * enable on this connection, and give him back the list
+	 * enable on this connection, and give him back the list.
+	 *
+	 * Give him a limited write bugdet
 	 */
-	if (lws_extension_server_handshake(wsi, &p))
+	if (lws_extension_server_handshake(wsi, &p, 192))
 		goto bail;
 #endif
 

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 468 - 146
EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/server.c


+ 255 - 60
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/service.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/service.c

@@ -27,6 +27,12 @@ lws_calllback_as_writeable(struct lws *wsi)
 	int n;
 
 	switch (wsi->mode) {
+	case LWSCM_RAW:
+		n = LWS_CALLBACK_RAW_WRITEABLE;
+		break;
+	case LWSCM_RAW_FILEDESC:
+		n = LWS_CALLBACK_RAW_WRITEABLE_FILE;
+		break;
 	case LWSCM_WS_CLIENT:
 		n = LWS_CALLBACK_CLIENT_WRITEABLE;
 		break;
@@ -58,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
@@ -71,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;
@@ -99,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
 
@@ -121,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 &&
@@ -142,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
@@ -153,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
@@ -172,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;
@@ -195,6 +209,8 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
 	 */
 
 	ret = 1;
+	if (wsi->mode == LWSCM_RAW || wsi->mode == LWSCM_RAW_FILEDESC)
+		ret = 0;
 	while (ret == 1) {
 
 		/* default to nobody has more to spill */
@@ -210,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)
 			/*
@@ -226,15 +242,15 @@ 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
 			 */
 			if (n != eff_buf.token_len) {
-				lwsl_err("Unable to spill ext %d vs %s\n",
+				lwsl_err("Unable to spill ext %d vs %d\n",
 							  eff_buf.token_len, n);
-				return -1;
+				goto bail_die;
 			}
 		} else
 			continue;
@@ -262,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;
@@ -270,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:
@@ -306,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__);
@@ -329,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
@@ -361,15 +413,15 @@ lws_service_timeout_check(struct lws *wsi, unsigned int sec)
 	 */
 	if ((time_t)sec > wsi->pending_timeout_limit) {
 //#if LWS_POSIX
-		if (wsi->sock != LWS_SOCK_INVALID && wsi->position_in_fds_table >= 0)
+		if (wsi->desc.sockfd != LWS_SOCK_INVALID && wsi->position_in_fds_table >= 0)
 			n = pt->fds[wsi->position_in_fds_table].events;
 
 		/* no need to log normal idle keepalive timeout */
 		if (wsi->pending_timeout != PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE)
-			lwsl_notice("wsi %p: TIMEDOUT WAITING on %d (did hdr %d, ah %p, wl %d, pfd events %d)\n",
+			lwsl_notice("wsi %p: TIMEDOUT WAITING on %d (did hdr %d, ah %p, wl %d, pfd events %d) %llu vs %llu\n",
 			    (void *)wsi, wsi->pending_timeout,
 			    wsi->hdr_parsing_completed, wsi->u.hdr.ah,
-			    pt->ah_wait_list_length, n);
+			    pt->ah_wait_list_length, n, (unsigned long long)sec, (unsigned long long)wsi->pending_timeout_limit);
 //#endif
 		/*
 		 * Since he failed a timeout, he already had a chance to do
@@ -481,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;
 	}
 
@@ -540,21 +593,22 @@ lws_http_client_read(struct lws *wsi, char **buf, int *len)
 {
 	int rlen, n;
 
+	rlen = lws_ssl_capable_read(wsi, (unsigned char *)*buf, *len);
+	*len = 0;
 
+	/* allow the source to signal he has data again next time */
+	lws_change_pollfd(wsi, 0, LWS_POLLIN);
 
-	rlen = lws_ssl_capable_read(wsi, (unsigned char *)*buf, *len);
-	if (rlen < 0)
+	if (rlen == LWS_SSL_CAPABLE_ERROR) {
+		lwsl_notice("%s: SSL capable error\n", __func__);
 		return -1;
+	}
 
-	*len = rlen;
-	if (rlen == 0)
+	if (rlen <= 0)
 		return 0;
 
-//	lwsl_err("%s: read %d\n", __func__, rlen);
-
-	/* allow the source to signal he has data again next time */
+	*len = rlen;
 	wsi->client_rx_avail = 0;
-	lws_change_pollfd(wsi, 0, LWS_POLLIN);
 
 	/*
 	 * server may insist on transfer-encoding: chunked,
@@ -569,14 +623,18 @@ spin_chunks:
 				break;
 			}
 			n = char_to_hex((*buf)[0]);
-			if (n < 0)
+			if (n < 0) {
+				lwsl_debug("chunking failure\n");
 				return -1;
+			}
 			wsi->chunk_remaining <<= 4;
 			wsi->chunk_remaining |= n;
 			break;
 		case ELCP_CR:
-			if ((*buf)[0] != '\x0a')
+			if ((*buf)[0] != '\x0a') {
+				lwsl_debug("chunking failure\n");
 				return -1;
+			}
 			wsi->chunk_parser = ELCP_CONTENT;
 			lwsl_info("chunk %d\n", wsi->chunk_remaining);
 			if (wsi->chunk_remaining)
@@ -588,8 +646,11 @@ spin_chunks:
 			break;
 
 		case ELCP_POST_CR:
-			if ((*buf)[0] != '\x0d')
+			if ((*buf)[0] != '\x0d') {
+				lwsl_debug("chunking failure\n");
+
 				return -1;
+			}
 
 			wsi->chunk_parser = ELCP_POST_LF;
 			break;
@@ -627,8 +688,11 @@ spin_chunks:
 #endif
 		if (user_callback_handle_rxflow(wsi->protocol->callback,
 				wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ,
-				wsi->user_space, *buf, n))
+				wsi->user_space, *buf, n)) {
+			lwsl_debug("%s: LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ returned -1\n", __func__);
+
 			return -1;
+		}
 
 	if (wsi->chunked && wsi->chunk_remaining) {
 		(*buf) += n;
@@ -639,30 +703,47 @@ spin_chunks:
 	if (wsi->chunked && !wsi->chunk_remaining)
 		wsi->chunk_parser = ELCP_POST_CR;
 
-	if (wsi->chunked && *len) {
+	if (wsi->chunked && *len)
 		goto spin_chunks;
-	}
 
 	if (wsi->chunked)
 		return 0;
 
-	wsi->u.http.content_remain -= n;
+	/* if we know the content length, decrement the content remaining */
+	if (wsi->u.http.content_length > 0)
+		wsi->u.http.content_remain -= n;
+
 	if (wsi->u.http.content_remain || !wsi->u.http.content_length)
 		return 0;
 
 completed:
 	if (user_callback_handle_rxflow(wsi->protocol->callback,
 			wsi, LWS_CALLBACK_COMPLETED_CLIENT_HTTP,
-			wsi->user_space, NULL, 0))
+			wsi->user_space, NULL, 0)) {
+		lwsl_debug("Completed call returned -1\n");
 		return -1;
+	}
 
-	if (lws_http_transaction_completed_client(wsi))
+	if (lws_http_transaction_completed_client(wsi)) {
+		lwsl_notice("%s: transaction completed says -1\n", __func__);
 		return -1;
+	}
 
 	return 0;
 }
 #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)
 {
@@ -695,6 +776,16 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
 
 		lws_plat_service_periodic(context);
 
+		/* retire unused deprecated context */
+#if !defined(LWS_PLAT_OPTEE) && !defined(LWS_WITH_ESP32)
+#if LWS_POSIX && !defined(_WIN32)
+		if (context->deprecated && !context->count_wsi_allocated) {
+			lwsl_notice("%s: ending deprecated context\n", __func__);
+			kill(getpid(), SIGINT);
+			return 0;
+		}
+#endif
+#endif
 		/* global timeout check once per second */
 
 		if (pollfd)
@@ -704,7 +795,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
 		while (wsi) {
 			/* we have to take copies, because he may be deleted */
 			wsi1 = wsi->timeout_list;
-			tmp_fd = wsi->sock;
+			tmp_fd = wsi->desc.sockfd;
 			if (lws_service_timeout_check(wsi, (unsigned int)now)) {
 				/* he did time out... */
 				if (tmp_fd == our_fd)
@@ -737,9 +828,9 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
 
 	if (context->ws_ping_pong_interval &&
 	    context->last_ws_ping_pong_check_s < now + 10) {
+		struct lws_vhost *vh = context->vhost_list;
 		context->last_ws_ping_pong_check_s = now;
 
-		struct lws_vhost *vh = context->vhost_list;
 		while (vh) {
 			for (n = 0; n < vh->count_protocols; n++) {
 				wsi = vh->same_vh_protocol_list[n];
@@ -804,7 +895,47 @@ 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... */
 
@@ -814,6 +945,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
 	case LWSCM_HTTP_SERVING_ACCEPTED:
 	case LWSCM_SERVER_LISTENER:
 	case LWSCM_SSL_ACK_PENDING:
+	case LWSCM_SSL_ACK_PENDING_RAW:
 		if (wsi->state == LWSS_CLIENT_HTTP_ESTABLISHED)
 			goto handled;
 
@@ -825,11 +957,43 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
 			goto handled;
 		}
 #endif
+		/* fallthru */
+	case LWSCM_RAW:
 		n = lws_server_socket_service(context, wsi, pollfd);
 		if (n) /* closed by above */
 			return 1;
 		goto handled;
 
+	case LWSCM_RAW_FILEDESC:
+
+		if (pollfd->revents & LWS_POLLOUT) {
+			n = lws_calllback_as_writeable(wsi);
+			if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {
+				lwsl_info("failed at set pollfd\n");
+				return 1;
+			}
+			if (n)
+				goto close_and_handled;
+		}
+		n = LWS_CALLBACK_RAW_RX;
+		if (wsi->mode == LWSCM_RAW_FILEDESC)
+			n = LWS_CALLBACK_RAW_RX_FILE;
+
+		if (pollfd->revents & LWS_POLLIN) {
+			if (user_callback_handle_rxflow(
+					wsi->protocol->callback,
+					wsi, n,
+					wsi->user_space, NULL, 0)) {
+				lwsl_debug("raw rx callback closed it\n");
+				goto close_and_handled;
+			}
+		}
+
+		if (pollfd->revents & LWS_POLLHUP)
+			goto close_and_handled;
+		n = 0;
+		goto handled;
+
 	case LWSCM_WS_SERVING:
 	case LWSCM_WS_CLIENT:
 	case LWSCM_HTTP2_SERVING:
@@ -838,11 +1002,11 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
 		/* 1: something requested a callback when it was OK to write */
 
 		if ((pollfd->revents & LWS_POLLOUT) &&
-		    (wsi->state == LWSS_ESTABLISHED ||
+		    ((wsi->state == LWSS_ESTABLISHED ||
 		     wsi->state == LWSS_HTTP2_ESTABLISHED ||
 		     wsi->state == LWSS_HTTP2_ESTABLISHED_PRE_SETTINGS ||
 		     wsi->state == LWSS_RETURNED_CLOSE_ALREADY ||
-		     wsi->state == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE) &&
+		     wsi->state == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE)) &&
 		    lws_handle_POLLOUT_event(wsi, pollfd)) {
 			if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY)
 				wsi->state = LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE;
@@ -940,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__);
@@ -955,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);
 			}
 		}
 
@@ -966,6 +1144,13 @@ drain:
 		    !wsi->told_user_closed) {
 
 			/*
+			 * In SSL mode we get POLLIN notification about
+			 * encrypted data in.
+			 *
+			 * But that is not necessarily related to decrypted
+			 * data out becoming available; in may need to perform
+			 * other in or out before that happens.
+			 *
 			 * simply mark ourselves as having readable data
 			 * and turn off our POLLIN
 			 */
@@ -978,8 +1163,10 @@ drain:
 			if (user_callback_handle_rxflow(
 					wsi->protocol->callback,
 					wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP,
-					wsi->user_space, NULL, 0))
+					wsi->user_space, NULL, 0)) {
+				lwsl_debug("LWS_CALLBACK_RECEIVE_CLIENT_HTTP closed it\n");
 				goto close_and_handled;
+			}
 		}
 #endif
 		/*
@@ -1013,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) {
@@ -1039,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;
 		}
@@ -1099,8 +1292,10 @@ drain:
 		break;
 #else
 		if ((pollfd->revents & LWS_POLLOUT) &&
-		    lws_handle_POLLOUT_event(wsi, pollfd))
+		    lws_handle_POLLOUT_event(wsi, pollfd)) {
+			lwsl_debug("POLLOUT event closed it\n");
 			goto close_and_handled;
+		}
 
 		n = lws_client_socket_service(context, wsi, pollfd);
 		if (n)
@@ -1142,6 +1337,6 @@ lws_service(struct lws_context *context, int timeout_ms)
 LWS_VISIBLE int
 lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
 {
-	return lws_plat_service_tsi(context, timeout_ms, tsi);
+	return _lws_plat_service_tsi(context, timeout_ms, tsi);
 }
 

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/sha-1.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/sha-1.c


+ 3 - 1
EVSE/GPL/libwebsockets-v2.1-stable/lib/smtp.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/smtp.c

@@ -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.
  *
@@ -211,6 +211,7 @@ lws_email_init(struct lws_email *email, uv_loop_t *loop, int max_content)
 	email->content = lws_malloc(max_content);
 	if (!email->content)
 		return 1;
+
 	email->max_content_size = max_content;
 	uv_timer_init(loop, &email->timeout_email);
 
@@ -235,5 +236,6 @@ lws_email_destroy(struct lws_email *email)
 		lws_free_set_NULL(email->content);
 
 	uv_timer_stop(&email->timeout_email);
+	uv_close((uv_handle_t *)&email->timeout_email, NULL);
 }
 

+ 176 - 89
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/ssl-client.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ssl-client.c

@@ -29,18 +29,91 @@ lws_ssl_bind_passphrase(SSL_CTX *ssl_ctx, struct lws_context_creation_info *info
 
 extern int lws_ssl_get_error(struct lws *wsi, int n);
 
+#ifdef USE_WOLFSSL
+#else
+
+static int
+OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
+{
+	SSL *ssl;
+	int n;
+	struct lws *wsi;
+
+	/* keep old behaviour accepting self-signed server certs */
+	if (!preverify_ok) {
+		int err = X509_STORE_CTX_get_error(x509_ctx);
+
+		if (err != X509_V_OK) {
+			ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+			wsi = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
+
+			if ((err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
+					err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) &&
+					wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED) {
+				lwsl_notice("accepting self-signed certificate (verify_callback)\n");
+				X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
+				return 1;	// ok
+			} else if ((err == X509_V_ERR_CERT_NOT_YET_VALID ||
+					err == X509_V_ERR_CERT_HAS_EXPIRED) &&
+					wsi->use_ssl & LCCSCF_ALLOW_EXPIRED) {
+				if (err == X509_V_ERR_CERT_NOT_YET_VALID)
+					lwsl_notice("accepting not yet valid certificate (verify_callback)\n");
+				else if (err == X509_V_ERR_CERT_HAS_EXPIRED)
+					lwsl_notice("accepting expired certificate (verify_callback)\n");
+				X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
+				return 1;	// ok
+			}
+		}
+	}
+
+	ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+	wsi = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
+
+	n = lws_get_context_protocol(wsi->context, 0).callback(wsi, LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION, x509_ctx, ssl, preverify_ok);
+
+	/* keep old behaviour if something wrong with server certs */
+	/* if ssl error is overruled in callback and cert is ok,
+	 * X509_STORE_CTX_set_error(x509_ctx, X509_V_OK); must be set and
+	 * return value is 0 from callback */
+	if (!preverify_ok) {
+		int err = X509_STORE_CTX_get_error(x509_ctx);
+
+		if (err != X509_V_OK) {	/* cert validation error was not handled in callback */
+			int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
+			const char* msg = X509_verify_cert_error_string(err);
+			lwsl_err("SSL error: %s (preverify_ok=%d;err=%d;depth=%d)\n", msg, preverify_ok, err, depth);
+			return preverify_ok;	// not ok
+		}
+	}
+	/* convert callback return code from 0 = OK to verify callback return value 1 = OK */
+	return !n;
+}
+#endif
+
 int
 lws_ssl_client_bio_create(struct lws *wsi)
 {
-#if defined(LWS_USE_POLARSSL)
-	return 0;
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
-	struct lws_context *context = wsi->context;
-	const char *hostname = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST);
+	char hostname[128], *p;
+
+	if (lws_hdr_copy(wsi, hostname, sizeof(hostname),
+			 _WSI_TOKEN_CLIENT_HOST) <= 0) {
+		lwsl_err("%s: Unable to get hostname\n", __func__);
+
+		return -1;
+	}
 
-	(void)hostname;
+	/*
+	 * remove any :port part on the hostname... necessary for network
+	 * connection but typical certificates do not contain it
+	 */
+	p = hostname;
+	while (*p) {
+		if (*p == ':') {
+			*p = '\0';
+			break;
+		}
+		p++;
+	}
 
 	wsi->ssl = SSL_new(wsi->vhost->ssl_client_ctx);
 	if (!wsi->ssl) {
@@ -60,9 +133,15 @@ lws_ssl_client_bio_create(struct lws *wsi)
 		X509_VERIFY_PARAM_set_hostflags(param,
 						X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
 		X509_VERIFY_PARAM_set1_host(param, hostname, 0);
-		/* Configure a non-zero callback if desired */
-		SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, 0);
 	}
+
+#endif
+
+#ifndef USE_WOLFSSL
+#ifndef USE_OLD_CYASSL
+	/* OpenSSL_client_verify_callback will be called @ SSL_connect() */
+	SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, OpenSSL_client_verify_callback);
+#endif
 #endif
 
 #ifndef USE_WOLFSSL
@@ -105,7 +184,7 @@ lws_ssl_client_bio_create(struct lws *wsi)
 #endif
 #endif /* USE_WOLFSSL */
 
-	wsi->client_bio = BIO_new_socket(wsi->sock, BIO_NOCLOSE);
+	wsi->client_bio = BIO_new_socket(wsi->desc.sockfd, BIO_NOCLOSE);
 	SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
 
 #ifdef USE_WOLFSSL
@@ -119,11 +198,9 @@ lws_ssl_client_bio_create(struct lws *wsi)
 #endif
 
 	SSL_set_ex_data(wsi->ssl, openssl_websocket_private_data_index,
-			context);
+			wsi);
 
 	return 0;
-#endif
-#endif
 }
 
 int
@@ -133,13 +210,9 @@ lws_ssl_client_connect1(struct lws *wsi)
 	int n = 0;
 
 	lws_latency_pre(context, wsi);
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+
 	n = SSL_connect(wsi->ssl);
-#endif
-#endif
+
 	lws_latency(context, wsi,
 	  "SSL_connect LWSCM_WSCL_ISSUE_HANDSHAKE", n, n > 0);
 
@@ -169,6 +242,17 @@ some_wait:
 
 			return 0; /* no error */
 		}
+
+		{
+			struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
+			char *p = (char *)&pt->serv_buf[0];
+			char *sb = p;
+
+			lwsl_err("ssl hs1 error, X509_V_ERR = %d: %s\n",
+				 n, ERR_error_string(n, sb));
+			lws_ssl_elaborate_error();
+		}
+
 		n = -1;
 	}
 
@@ -177,22 +261,17 @@ some_wait:
 		 * retry if new data comes until we
 		 * run into the connection timeout or win
 		 */
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
-		n = ERR_get_error();
 
-		if (n != SSL_ERROR_NONE) {
+		unsigned long error = ERR_get_error();
+
+		if (error != SSL_ERROR_NONE) {
 			struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
 			char *p = (char *)&pt->serv_buf[0];
 			char *sb = p;
 			lwsl_err("SSL connect error %lu: %s\n",
-				n, ERR_error_string(n, sb));
+				error, ERR_error_string(error, sb));
 			return -1;
 		}
-#endif
-#endif
 	}
 
 	return 1;
@@ -202,26 +281,16 @@ int
 lws_ssl_client_connect2(struct lws *wsi)
 {
 	struct lws_context *context = wsi->context;
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
 	struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
 	char *p = (char *)&pt->serv_buf[0];
 	char *sb = p;
-#endif
-#endif
 	int n = 0;
 
 	if (wsi->mode == LWSCM_WSCL_WAITING_SSL) {
 		lws_latency_pre(context, wsi);
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
 		n = SSL_connect(wsi->ssl);
-#endif
-#endif
+		lwsl_notice("%s: SSL_connect says %d\n", __func__, n);
+
 		lws_latency(context, wsi,
 			    "SSL_connect LWSCM_WSCL_WAITING_SSL", n, n > 0);
 
@@ -229,6 +298,8 @@ lws_ssl_client_connect2(struct lws *wsi)
 			n = lws_ssl_get_error(wsi, n);
 
 			if (n == SSL_ERROR_WANT_READ) {
+				lwsl_info("SSL_connect WANT_READ... retrying\n");
+
 				wsi->mode = LWSCM_WSCL_WAITING_SSL;
 
 				return 0; /* no error */
@@ -254,6 +325,7 @@ lws_ssl_client_connect2(struct lws *wsi)
 
 				return 0; /* no error */
 			}
+
 			n = -1;
 		}
 
@@ -262,25 +334,15 @@ lws_ssl_client_connect2(struct lws *wsi)
 			 * retry if new data comes until we
 			 * run into the connection timeout or win
 			 */
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
-			n = ERR_get_error();
-			if (n != SSL_ERROR_NONE) {
+			unsigned long error = ERR_get_error();
+			if (error != SSL_ERROR_NONE) {
 				lwsl_err("SSL connect error %lu: %s\n",
-					 n, ERR_error_string(n, sb));
+					 error, ERR_error_string(error, sb));
 				return -1;
 			}
-#endif
-#endif
 		}
 	}
 
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
 #ifndef USE_WOLFSSL
 	/*
 	 * See comment above about wolfSSL certificate
@@ -294,8 +356,15 @@ lws_ssl_client_connect2(struct lws *wsi)
 	if (n != X509_V_OK) {
 		if ((n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
 		     n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) &&
-		     wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED) {
+		     (wsi->use_ssl & LCCSCF_ALLOW_SELFSIGNED)) {
 			lwsl_notice("accepting self-signed certificate\n");
+		} else if ((n == X509_V_ERR_CERT_NOT_YET_VALID ||
+		            n == X509_V_ERR_CERT_HAS_EXPIRED) &&
+		     (wsi->use_ssl & LCCSCF_ALLOW_EXPIRED)) {
+			lwsl_notice("accepting expired certificate\n");
+		} else if (n == X509_V_ERR_CERT_NOT_YET_VALID) {
+			lwsl_notice("Cert is from the future... "
+				    "probably our clock... accepting...\n");
 		} else {
 			lwsl_err("server's cert didn't look good, X509_V_ERR = %d: %s\n",
 				 n, ERR_error_string(n, sb));
@@ -303,9 +372,8 @@ lws_ssl_client_connect2(struct lws *wsi)
 			return -1;
 		}
 	}
+
 #endif /* USE_WOLFSSL */
-#endif
-#endif
 
 	return 1;
 }
@@ -314,16 +382,28 @@ lws_ssl_client_connect2(struct lws *wsi)
 int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 				struct lws_vhost *vhost)
 {
-#if defined(LWS_USE_POLARSSL)
-	return 0;
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
-	SSL_METHOD *method;
+	SSL_METHOD *method = NULL;
 	struct lws wsi;
-	int error;
+	unsigned long error;
+	const char *cipher_list = info->ssl_cipher_list;
+	const char *ca_filepath = info->ssl_ca_filepath;
+	const char *cert_filepath = info->ssl_cert_filepath;
+	const char *private_key_filepath = info->ssl_private_key_filepath;
 	int n;
 
+	/*
+	 *  for backwards-compatibility default to using ssl_... members, but
+	 * if the newer client-specific ones are given, use those
+	 */
+	if (info->client_ssl_cipher_list)
+		cipher_list = info->client_ssl_cipher_list;
+	if (info->client_ssl_ca_filepath)
+		ca_filepath = info->client_ssl_ca_filepath;
+	if (info->client_ssl_cert_filepath)
+		cert_filepath = info->client_ssl_cert_filepath;
+	if (info->client_ssl_private_key_filepath)
+		private_key_filepath = info->client_ssl_private_key_filepath;
+
 	if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
 		return 0;
 
@@ -341,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",
@@ -364,9 +451,8 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 #endif
 	SSL_CTX_set_options(vhost->ssl_client_ctx,
 			    SSL_OP_CIPHER_SERVER_PREFERENCE);
-	if (info->ssl_cipher_list)
-		SSL_CTX_set_cipher_list(vhost->ssl_client_ctx,
-						info->ssl_cipher_list);
+	if (cipher_list)
+		SSL_CTX_set_cipher_list(vhost->ssl_client_ctx, cipher_list);
 
 #ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
 	if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
@@ -375,7 +461,7 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 #endif
 
 	/* openssl init for cert verification (for client sockets) */
-	if (!info->ssl_ca_filepath) {
+	if (!ca_filepath) {
 		if (!SSL_CTX_load_verify_locations(
 			vhost->ssl_client_ctx, NULL,
 					     LWS_OPENSSL_CLIENT_CERTS))
@@ -383,15 +469,16 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 			    "Unable to load SSL Client certs from %s "
 			    "(set by --with-client-cert-dir= "
 			    "in configure) --  client ssl isn't "
-			    "going to work", LWS_OPENSSL_CLIENT_CERTS);
+			    "going to work\n", LWS_OPENSSL_CLIENT_CERTS);
 	} else
 		if (!SSL_CTX_load_verify_locations(
-			vhost->ssl_client_ctx, info->ssl_ca_filepath,
-							  NULL))
+			vhost->ssl_client_ctx, ca_filepath, NULL)) {
 			lwsl_err(
 				"Unable to load SSL Client certs "
 				"file from %s -- client ssl isn't "
-				"going to work", info->ssl_ca_filepath);
+				"going to work\n", info->client_ssl_ca_filepath);
+			lws_ssl_elaborate_error();
+		}
 		else
 			lwsl_info("loaded ssl_ca_filepath\n");
 
@@ -401,30 +488,32 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 	 */
 
 	/* support for client-side certificate authentication */
-	if (info->ssl_cert_filepath) {
+	if (cert_filepath) {
+		lwsl_notice("%s: doing cert filepath\n", __func__);
 		n = SSL_CTX_use_certificate_chain_file(vhost->ssl_client_ctx,
-						       info->ssl_cert_filepath);
-		if (n != 1) {
-			lwsl_err("problem getting cert '%s' %lu: %s\n",
-				info->ssl_cert_filepath,
-				ERR_get_error(),
-				ERR_error_string(ERR_get_error(),
-				(char *)vhost->context->pt[0].serv_buf));
+						       cert_filepath);
+		if (n < 1) {
+			lwsl_err("problem %d getting cert '%s'\n", n,
+				 cert_filepath);
+			lws_ssl_elaborate_error();
 			return 1;
 		}
+		lwsl_notice("Loaded client cert %s\n", cert_filepath);
 	}
-	if (info->ssl_private_key_filepath) {
+
+	if (private_key_filepath) {
+		lwsl_notice("%s: doing private key filepath\n", __func__);
 		lws_ssl_bind_passphrase(vhost->ssl_client_ctx, info);
 		/* set the private key from KeyFile */
 		if (SSL_CTX_use_PrivateKey_file(vhost->ssl_client_ctx,
-		    info->ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
-			lwsl_err("use_PrivateKey_file '%s' %lu: %s\n",
-				info->ssl_private_key_filepath,
-				ERR_get_error(),
-				ERR_error_string(ERR_get_error(),
-				      (char *)vhost->context->pt[0].serv_buf));
+		    private_key_filepath, SSL_FILETYPE_PEM) != 1) {
+			lwsl_err("use_PrivateKey_file '%s'\n",
+				 private_key_filepath);
+			lws_ssl_elaborate_error();
 			return 1;
 		}
+		lwsl_notice("Loaded client cert private key %s\n",
+			    private_key_filepath);
 
 		/* verify private key */
 		if (!SSL_CTX_check_private_key(vhost->ssl_client_ctx)) {
@@ -446,6 +535,4 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 				       vhost->ssl_client_ctx, NULL, 0);
 
 	return 0;
-#endif
-#endif
 }

+ 1 - 1
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/ssl-http2.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ssl-http2.c

@@ -100,7 +100,7 @@ lws_context_init_http2_ssl(struct lws_vhost *vhost)
 	lwsl_notice(" HTTP2 / ALPN enabled\n");
 #else
 	lwsl_notice(
-		" HTTP2 / ALPN configured but not supported by OpenSSL 0x%x\n",
+		" HTTP2 / ALPN configured but not supported by OpenSSL 0x%lx\n",
 		    OPENSSL_VERSION_NUMBER);
 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
 }

+ 9 - 86
EVSE/GPL/libwebsockets-v2.1-stable-org/lib/ssl-server.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ssl-server.c

@@ -21,11 +21,6 @@
 
 #include "private-libwebsockets.h"
 
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
-
 extern int openssl_websocket_private_data_index,
     openssl_SSL_CTX_private_data_index;
 
@@ -37,8 +32,7 @@ OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
 {
 	SSL *ssl;
 	int n;
-	struct lws_vhost *vh;
-	struct lws wsi;
+	struct lws *wsi;
 
 	ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
 		SSL_get_ex_data_X509_STORE_CTX_idx());
@@ -47,17 +41,9 @@ OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
 	 * !!! nasty openssl requires the index to come as a library-scope
 	 * static
 	 */
-	vh = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
+	wsi = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
 
-	/*
-	 * give him a fake wsi with context set, so he can use lws_get_context()
-	 * in the callback
-	 */
-	memset(&wsi, 0, sizeof(wsi));
-	wsi.vhost = vh;
-	wsi.context = vh->context;
-
-	n = vh->protocols[0].callback(&wsi,
+	n = wsi->vhost->protocols[0].callback(wsi,
 			LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
 					   x509_ctx, ssl, preverify_ok);
 
@@ -195,23 +181,19 @@ lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg)
 }
 #endif
 
-#endif
-#endif
-
 LWS_VISIBLE int
 lws_context_init_server_ssl(struct lws_context_creation_info *info,
 			    struct lws_vhost *vhost)
 {
 	struct lws_context *context = vhost->context;
 	struct lws wsi;
-	int error;
+	unsigned long error;
 	int n;
 
 	if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) {
 		vhost->use_ssl = 0;
 		return 0;
 	}
-
 	if (info->port != CONTEXT_PORT_NO_LISTEN) {
 
 		vhost->use_ssl = info->ssl_cert_filepath != NULL;
@@ -236,66 +218,6 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 	(void)n;
 	(void)error;
 
-#if defined(LWS_USE_POLARSSL)
-	lwsl_notice(" Compiled with PolarSSL support\n");
-
-	vhost->ssl_ctx = lws_zalloc(sizeof (*vhost->ssl_ctx));
-
-	/* Load the trusted CA */
-
-	if (info->ssl_ca_filepath) {
-		n = x509_crt_parse_file(&vhost->ssl_ctx->ca,
-					info->ssl_ca_filepath);
-
-		if (n < 0) {
-//			error_strerror(ret, errorbuf, sizeof(errorbuf));
-			lwsl_err("%s: Failed to load ca cert\n", __func__);
-			return -1;
-		}
-	}
-
-	/* Load our cert */
-
-	if (info->ssl_cert_filepath) {
-		n = x509_crt_parse_file(&vhost->ssl_ctx->certificate,
-					info->ssl_cert_filepath);
-
-		if (n < 0) {
-//			error_strerror(ret, errorbuf, sizeof(errorbuf));
-			lwsl_err("%s: Failed to load cert\n", __func__);
-			return -1;
-		}
-	}
-
-	/* Load cert private key */
-
-	if (info->ssl_private_key_filepath) {
-		pk_context pk;
-		pk_init(&pk);
-		n = pk_parse_keyfile(&pk, info->ssl_private_key_filepath,
-				     info->ssl_private_key_password);
-
-		if (!n && !pk_can_do(&pk, POLARSSL_PK_RSA))
-			n = POLARSSL_ERR_PK_TYPE_MISMATCH;
-
-		if (!n)
-			rsa_copy(&vhost->ssl_ctx->key, pk_rsa(pk));
-		else
-			rsa_free(&vhost->ssl_ctx->key);
-		pk_free(&pk);
-
-		if (n) {
-			//error_strerror(ret, errorbuf, sizeof(errorbuf));
-			lwsl_err("%s: error reading private key\n", __func__);
-
-			return -1;
-		}
-	}
-#else
-#if defined(LWS_USE_MBEDTLS)
-	lwsl_notice(" Compiled with mbedTLS support\n");
-#else
-
 	/*
 	 * Firefox insists on SSLv23 not SSLv3
 	 * Konq disables SSLv2 by default now, SSLv23 works
@@ -392,10 +314,14 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 
 	if (info->ssl_options_set)
 		SSL_CTX_set_options(vhost->ssl_ctx, info->ssl_options_set);
+
+/* SSL_clear_options introduced in 0.9.8m */
+#if (OPENSSL_VERSION_NUMBER >= 0x009080df) && !defined(USE_WOLFSSL)
 	if (info->ssl_options_clear)
 		SSL_CTX_clear_options(vhost->ssl_ctx, info->ssl_options_clear);
+#endif
 
-	lwsl_info(" SSL options 0x%X\n",
+	lwsl_info(" SSL options 0x%lX\n",
 		    SSL_CTX_get_options(vhost->ssl_ctx));
 
 	if (vhost->use_ssl) {
@@ -453,9 +379,6 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 		lws_context_init_http2_ssl(vhost);
 	}
 
-#endif
-#endif
-
 	return 0;
 }
 

+ 135 - 232
EVSE/GPL/libwebsockets-v2.1-stable/lib/ssl.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lib/ssl.c

@@ -21,36 +21,9 @@
 
 #include "private-libwebsockets.h"
 
-#if defined(LWS_USE_POLARSSL)
-static const int ciphers[] =
-{
-	TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
-	TLS_RSA_WITH_AES_256_CBC_SHA,
-	TLS_RSA_WITH_AES_128_CBC_SHA,
-	0
-};
-
-static int urandom_bytes(void *ctx, unsigned char *dest, size_t len)
-{
-	int cur;
-	int fd = open("/dev/urandom", O_RDONLY);
-
-	while (len) {
-		cur = read(fd, dest, len);
-		if (cur < 0)
-			continue;
-		len -= cur;
-	}
-	close(fd);
-
-	return 0;
-}
-
-static void pssl_debug(void *ctx, int level, const char *str)
-{
-    lwsl_err("PolarSSL [level %d]: %s", level, str);
-}
-
+/* workaround for mingw */
+#if !defined(ECONNABORTED)
+#define ECONNABORTED 103
 #endif
 
 int openssl_websocket_private_data_index,
@@ -58,26 +31,56 @@ int openssl_websocket_private_data_index,
 
 int lws_ssl_get_error(struct lws *wsi, int n)
 {
-#if defined(LWS_USE_POLARSSL)
-#define ERR_error_string(a, b) ""
-	return n;
-#else
-#if defined(LWS_USE_MBEDTLS)
-	return n;
-#else
 	return SSL_get_error(wsi->ssl, n);
-#endif
-#endif
+}
+
+/* Copies a string describing the code returned by lws_ssl_get_error(),
+ * which may also contain system error information in the case of SSL_ERROR_SYSCALL,
+ * into buf up to len.
+ * Returns a pointer to buf.
+ *
+ * Note: the lws_ssl_get_error() code is *not* an error code that can be passed
+ * to ERR_error_string(),
+ *
+ * ret is the return value originally passed to lws_ssl_get_error(), needed to disambiguate
+ * SYS_ERROR_SYSCALL.
+ *
+ * See man page for SSL_get_error().
+ *
+ * Not thread safe, uses strerror()
+ */
+char* lws_ssl_get_error_string(int status, int ret, char *buf, size_t len) {
+	switch (status) {
+	case SSL_ERROR_NONE: return strncpy(buf, "SSL_ERROR_NONE", len);
+	case SSL_ERROR_ZERO_RETURN: return strncpy(buf, "SSL_ERROR_ZERO_RETURN", len);
+	case SSL_ERROR_WANT_READ: return strncpy(buf, "SSL_ERROR_WANT_READ", len);
+	case SSL_ERROR_WANT_WRITE: return strncpy(buf, "SSL_ERROR_WANT_WRITE", len);
+	case SSL_ERROR_WANT_CONNECT: return strncpy(buf, "SSL_ERROR_WANT_CONNECT", len);
+	case SSL_ERROR_WANT_ACCEPT: return strncpy(buf, "SSL_ERROR_WANT_ACCEPT", len);
+	case SSL_ERROR_WANT_X509_LOOKUP: return strncpy(buf, "SSL_ERROR_WANT_X509_LOOKUP", len);
+	case SSL_ERROR_SYSCALL:
+		switch (ret) {
+                case 0:
+                        lws_snprintf(buf, len, "SSL_ERROR_SYSCALL: EOF");
+                        return buf;
+                case -1:
+#ifndef LWS_PLAT_OPTEE
+			lws_snprintf(buf, len, "SSL_ERROR_SYSCALL: %s", strerror(errno));
+#else
+			lws_snprintf(buf, len, "SSL_ERROR_SYSCALL: %d", errno);
+#endif
+			return buf;
+                default:
+                        return strncpy(buf, "SSL_ERROR_SYSCALL", len);
+	}
+	case SSL_ERROR_SSL: return "SSL_ERROR_SSL";
+	default: return "SSL_ERROR_UNKNOWN";
+	}
 }
 
 void
 lws_ssl_elaborate_error(void)
 {
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
-
 	char buf[256];
 	u_long err;
 
@@ -85,15 +88,8 @@ lws_ssl_elaborate_error(void)
 		ERR_error_string_n(err, buf, sizeof(buf));
 		lwsl_err("*** %s\n", buf);
 	}
-#endif
-#endif
 }
 
-
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
 static int
 lws_context_init_ssl_pem_passwd_cb(char * buf, int size, int rwflag, void *userdata)
 {
@@ -105,18 +101,13 @@ lws_context_init_ssl_pem_passwd_cb(char * buf, int size, int rwflag, void *userd
 
 	return strlen(buf);
 }
-#endif
-#endif
 
 void
 lws_ssl_bind_passphrase(SSL_CTX *ssl_ctx, struct lws_context_creation_info *info)
 {
 	if (!info->ssl_private_key_password)
 		return;
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+
 	/*
 	 * password provided, set ssl callback and user data
 	 * for checking password which will be trigered during
@@ -124,8 +115,6 @@ lws_ssl_bind_passphrase(SSL_CTX *ssl_ctx, struct lws_context_creation_info *info
 	 */
 	SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)info);
 	SSL_CTX_set_default_passwd_cb(ssl_ctx, lws_context_init_ssl_pem_passwd_cb);
-#endif
-#endif
 }
 
 int
@@ -138,17 +127,12 @@ lws_context_init_ssl_library(struct lws_context_creation_info *info)
 	lwsl_notice(" Compiled with wolfSSL support\n");
 #endif
 #else
-#if defined(LWS_USE_POLARSSL)
-	lwsl_notice(" Compiled with PolarSSL support\n");
-#else
-#if defined(LWS_USE_MBEDTLS)
-	lwsl_notice(" Compiled with mbedTLS support\n");
+#if defined(LWS_USE_BORINGSSL)
+	lwsl_notice(" Compiled with BoringSSL support\n");
 #else
 	lwsl_notice(" Compiled with OpenSSL support\n");
 #endif
 #endif
-#endif
-
 	if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) {
 		lwsl_notice(" SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT\n");
 		return 0;
@@ -156,10 +140,8 @@ lws_context_init_ssl_library(struct lws_context_creation_info *info)
 
 	/* basic openssl init */
 
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+	lwsl_notice("Doing SSL library init\n");
+
 	SSL_library_init();
 
 	OpenSSL_add_all_algorithms();
@@ -170,8 +152,6 @@ lws_context_init_ssl_library(struct lws_context_creation_info *info)
 
 	openssl_SSL_CTX_private_data_index = SSL_CTX_get_ex_new_index(0,
 			NULL, NULL, NULL, NULL);
-#endif
-#endif
 
 	return 0;
 }
@@ -184,23 +164,20 @@ lws_ssl_destroy(struct lws_vhost *vhost)
 			   LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT))
 		return;
 
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
-
 	if (vhost->ssl_ctx)
 		SSL_CTX_free(vhost->ssl_ctx);
 	if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
 		SSL_CTX_free(vhost->ssl_client_ctx);
 
-#if (OPENSSL_VERSION_NUMBER < 0x10100006L)
-#if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_WOLFSSL)
+// after 1.1.0 no need
+#if (OPENSSL_VERSION_NUMBER <  0x10100000)
+// <= 1.0.1f = old api, 1.0.1g+ = new api
+#if (OPENSSL_VERSION_NUMBER <= 0x1000106f) || defined(USE_WOLFSSL)
 	ERR_remove_state(0);
 #else
-#if (OPENSSL_VERSION_NUMBER >= 0x10100005L) && \
-	!defined(LIBRESSL_VERSION_NUMBER) && \
-	!defined(OPENSSL_IS_BORINGSSL)
+#if OPENSSL_VERSION_NUMBER >= 0x1010005f && \
+    !defined(LIBRESSL_VERSION_NUMBER) && \
+    !defined(OPENSSL_IS_BORINGSSL)
 	ERR_remove_thread_state();
 #else
 	ERR_remove_thread_state(NULL);
@@ -210,25 +187,17 @@ lws_ssl_destroy(struct lws_vhost *vhost)
 	EVP_cleanup();
 	CRYPTO_cleanup_all_ex_data();
 #endif
-#endif
-#endif
 }
 
 LWS_VISIBLE void
 lws_decode_ssl_error(void)
 {
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
 	char buf[256];
 	u_long err;
 	while ((err = ERR_get_error()) != 0) {
 		ERR_error_string_n(err, buf, sizeof(buf));
 		lwsl_err("*** %lu %s\n", err, buf);
 	}
-#endif
-#endif
 }
 
 LWS_VISIBLE void
@@ -265,32 +234,50 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
 	struct lws_context *context = wsi->context;
 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
 	int n = 0;
+ int ssl_read_errno = 0;
 
 	if (!wsi->ssl)
 		return lws_ssl_capable_read_no_ssl(wsi, buf, len);
 
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
 	n = SSL_read(wsi->ssl, buf, len);
-#endif
-#endif
 
 	/* manpage: returning 0 means connection shut down */
-	if (!n)
+	if (!n) {
+  n = lws_ssl_get_error(wsi, n);
+
+  if (n == SSL_ERROR_ZERO_RETURN)
+   return LWS_SSL_CAPABLE_ERROR;
+
+  if (n == SSL_ERROR_SYSCALL) {
+   int err = ERR_get_error();
+   if (err == 0
+     && (ssl_read_errno == EPIPE
+      || ssl_read_errno == ECONNABORTED
+      || ssl_read_errno == 0))
+     return LWS_SSL_CAPABLE_ERROR;
+  }
+
+		lwsl_err("%s failed: %s\n",__func__,
+			 ERR_error_string(lws_ssl_get_error(wsi, 0), NULL));
+		lws_decode_ssl_error();
+
 		return LWS_SSL_CAPABLE_ERROR;
+	}
 
 	if (n < 0) {
 		n = lws_ssl_get_error(wsi, n);
 		if (n ==  SSL_ERROR_WANT_READ || n ==  SSL_ERROR_WANT_WRITE)
 			return LWS_SSL_CAPABLE_MORE_SERVICE;
 
+		lwsl_err("%s failed2: %s\n",__func__,
+				 ERR_error_string(lws_ssl_get_error(wsi, 0), NULL));
+			lws_decode_ssl_error();
+
 		return LWS_SSL_CAPABLE_ERROR;
 	}
 
 	if (wsi->vhost)
-		wsi->vhost->rx += n;
+		wsi->vhost->conn_stats.rx += n;
 
 	lws_restart_ws_ping_pong_timer(wsi);
 
@@ -305,16 +292,10 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
 		goto bail;
 	if (!wsi->ssl)
 		goto bail;
-#if defined(LWS_USE_POLARSSL)
-	if (ssl_get_bytes_avail(wsi->ssl) <= 0)
-		goto bail;
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+
 	if (!SSL_pending(wsi->ssl))
 		goto bail;
-#endif
-#endif
+
 	if (wsi->pending_read_list_next)
 		return n;
 	if (wsi->pending_read_list_prev)
@@ -342,33 +323,20 @@ lws_ssl_pending(struct lws *wsi)
 {
 	if (!wsi->ssl)
 		return 0;
-#if defined(LWS_USE_POLARSSL)
-	return ssl_get_bytes_avail(wsi->ssl) > 0;
-#else
-#if defined(LWS_USE_MBEDTLS)
-	return ssl_get_bytes_avail(wsi->ssl) > 0;;
-#else
+
 	return SSL_pending(wsi->ssl);
-#endif
-#endif
 }
 
 LWS_VISIBLE int
 lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len)
 {
 	int n;
+ int ssl_read_errno = 0;
 
 	if (!wsi->ssl)
 		return lws_ssl_capable_write_no_ssl(wsi, buf, len);
 
-#if defined(LWS_USE_POLARSSL)
-	n = ssl_write(wsi->ssl, buf, len);
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
 	n = SSL_write(wsi->ssl, buf, len);
-#endif
-#endif
 	if (n > 0)
 		return n;
 
@@ -379,6 +347,22 @@ lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len)
 		return LWS_SSL_CAPABLE_MORE_SERVICE;
 	}
 
+ if (n == SSL_ERROR_ZERO_RETURN)
+  return LWS_SSL_CAPABLE_ERROR;
+
+ if (n == SSL_ERROR_SYSCALL) {
+  int err = ERR_get_error();
+  if (err == 0
+    && (ssl_read_errno == EPIPE
+     || ssl_read_errno == ECONNABORTED
+     || ssl_read_errno == 0))
+    return LWS_SSL_CAPABLE_ERROR;
+ }
+
+ lwsl_err("%s failed: %s\n",__func__,
+   ERR_error_string(lws_ssl_get_error(wsi, 0), NULL));
+ lws_decode_ssl_error();
+
 	return LWS_SSL_CAPABLE_ERROR;
 }
 
@@ -390,19 +374,10 @@ lws_ssl_close(struct lws *wsi)
 	if (!wsi->ssl)
 		return 0; /* not handled */
 
-#if defined(LWS_USE_POLARSSL)
-	ssl_close_notify(wsi->ssl);
-	(void)n; /* we need to close the fd? */
-	ssl_free(wsi->ssl);
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
 	n = SSL_get_fd(wsi->ssl);
 	SSL_shutdown(wsi->ssl);
 	compatible_close(n);
 	SSL_free(wsi->ssl);
-#endif
-#endif
 	wsi->ssl = NULL;
 
 	return 1; /* handled */
@@ -416,59 +391,22 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 	struct lws_context *context = wsi->context;
 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
 	int n, m;
-#if !defined(USE_WOLFSSL) && !defined(LWS_USE_POLARSSL) && !defined(LWS_USE_MBEDTLS)
+#if !defined(USE_WOLFSSL)
 	BIO *bio;
 #endif
+        char buf[256];
 
 	if (!LWS_SSL_ENABLED(wsi->vhost))
 		return 0;
 
 	switch (wsi->mode) {
 	case LWSCM_SSL_INIT:
-
+	case LWSCM_SSL_INIT_RAW:
 		if (wsi->ssl)
 			lwsl_err("%s: leaking ssl\n", __func__);
 		if (accept_fd == LWS_SOCK_INVALID)
 			assert(0);
 
-#if defined(LWS_USE_POLARSSL)
-	{
-		ssl_session *ssn;
-		int rc;
-
-		wsi->ssl = lws_zalloc(sizeof(ssl_context));
-		ssn = lws_zalloc(sizeof(ssl_session));
-
-		rc = ssl_init(wsi->ssl);
-		if (rc) {
-			lwsl_err("ssl_init failed\n");
-			goto fail;
-		}
-
-		ssl_set_endpoint(wsi->ssl, SSL_IS_SERVER);
-		ssl_set_authmode(wsi->ssl, SSL_VERIFY_OPTIONAL);
-		ssl_set_rng(wsi->ssl, urandom_bytes, NULL);
-		ssl_set_dbg(wsi->ssl, pssl_debug, NULL);
-		ssl_set_bio(wsi->ssl, net_recv, &wsi->sock, net_send, &wsi->sock);
-
-		ssl_set_ciphersuites(wsi->ssl, ciphers);
-
-		ssl_set_session(wsi->ssl, ssn);
-
-		ssl_set_ca_chain(wsi->ssl, &wsi->vhost->ssl_ctx->ca,
-				 NULL, NULL);
-
-		ssl_set_own_cert_rsa(wsi->ssl,
-				&wsi->vhost->ssl_ctx->certificate,
-				&wsi->vhost->ssl_ctx->key);
-
-//		ssl_set_dh_param(wsi->ssl, my_dhm_P, my_dhm_G);
-
-		lwsl_err("%s: polarssl init done\n", __func__);
-	}
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
 		wsi->ssl = SSL_new(wsi->vhost->ssl_ctx);
 		if (wsi->ssl == NULL) {
 			lwsl_err("SSL_new failed: %s\n",
@@ -480,11 +418,9 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 		}
 
 		SSL_set_ex_data(wsi->ssl,
-			openssl_websocket_private_data_index, wsi->vhost);
+			openssl_websocket_private_data_index, wsi);
 
 		SSL_set_fd(wsi->ssl, accept_fd);
-#endif
-#endif
 
 #ifdef USE_WOLFSSL
 #ifdef USE_OLD_CYASSL
@@ -492,11 +428,6 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 #else
 		wolfSSL_set_using_nonblock(wsi->ssl, 1);
 #endif
-#else
-#if defined(LWS_USE_POLARSSL)
-
-#else
-#if defined(LWS_USE_MBEDTLS)
 #else
 		SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
 		bio = SSL_get_rbio(wsi->ssl);
@@ -509,8 +440,6 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 			BIO_set_nbio(bio, 1); /* nonblocking */
 		else
 			lwsl_notice("NULL rbio\n");
-#endif
-#endif
 #endif
 
 		/*
@@ -519,7 +448,11 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 		 * pieces come if we're not sorted yet
 		 */
 
-		wsi->mode = LWSCM_SSL_ACK_PENDING;
+		if (wsi->mode == LWSCM_SSL_INIT)
+			wsi->mode = LWSCM_SSL_ACK_PENDING;
+		else
+			wsi->mode = LWSCM_SSL_ACK_PENDING_RAW;
+
 		if (insert_wsi_socket_into_fds(context, wsi)) {
 			lwsl_err("%s: failed to insert into fds\n", __func__);
 			goto fail;
@@ -533,7 +466,7 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 		/* fallthru */
 
 	case LWSCM_SSL_ACK_PENDING:
-
+	case LWSCM_SSL_ACK_PENDING_RAW:
 		if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {
 			lwsl_err("%s: lws_change_pollfd failed\n", __func__);
 			goto fail;
@@ -541,7 +474,7 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 
 		lws_latency_pre(context, wsi);
 
-		n = recv(wsi->sock, (char *)pt->serv_buf, context->pt_serv_buf_size,
+		n = recv(wsi->desc.sockfd, (char *)pt->serv_buf, context->pt_serv_buf_size,
 			 MSG_PEEK);
 
 		/*
@@ -564,16 +497,9 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 				* connection upgrade directly.
 				*/
 				wsi->use_ssl = 0;
-#if defined(LWS_USE_POLARSSL)
-				ssl_close_notify(wsi->ssl);
-				ssl_free(wsi->ssl);
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+
 				SSL_shutdown(wsi->ssl);
 				SSL_free(wsi->ssl);
-#endif
-#endif
 				wsi->ssl = NULL;
 				if (lws_check_opt(context->options,
 				    LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS))
@@ -600,14 +526,8 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 		}
 
 		/* normal SSL connection processing path */
-#if defined(LWS_USE_POLARSSL)
-		n = ssl_handshake(wsi->ssl);
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+
 		n = SSL_accept(wsi->ssl);
-#endif
-#endif
 		lws_latency(context, wsi,
 			"SSL_accept LWSCM_SSL_ACK_PENDING\n", n, n == 1);
 
@@ -615,8 +535,6 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
 			goto accepted;
 
 		m = lws_ssl_get_error(wsi, n);
-		lwsl_debug("SSL_accept failed %d / %s\n",
-			   m, ERR_error_string(m, NULL));
 go_again:
 		if (m == SSL_ERROR_WANT_READ) {
 			if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) {
@@ -635,9 +553,9 @@ go_again:
 
 			break;
 		}
-		lwsl_err("SSL_accept failed skt %u: %s\n",
-			   wsi->sock, ERR_error_string(m, NULL));
 
+                lwsl_err("SSL_accept failed socket %u: %s\n", wsi->desc.sockfd,
+                         lws_ssl_get_error_string(m, n, buf, sizeof(buf)));
 		lws_ssl_elaborate_error();
 		goto fail;
 
@@ -646,7 +564,10 @@ accepted:
 		lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
 				context->timeout_secs);
 
-		wsi->mode = LWSCM_HTTP_SERVING;
+		if (wsi->mode == LWSCM_SSL_ACK_PENDING_RAW)
+			wsi->mode = LWSCM_RAW;
+		else
+			wsi->mode = LWSCM_HTTP_SERVING;
 
 		lws_http2_configure_if_upgraded(wsi);
 
@@ -663,42 +584,26 @@ fail:
 void
 lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost)
 {
-	if (vhost->ssl_ctx) {
-#if defined(LWS_USE_POLARSSL)
-		lws_free(vhost->ssl_ctx);
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+	if (vhost->ssl_ctx)
 		SSL_CTX_free(vhost->ssl_ctx);
-#endif
-#endif
-	}
-	if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx) {
-#if defined(LWS_USE_POLARSSL)
-		lws_free(vhost->ssl_client_ctx);
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
+
+	if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx)
 		SSL_CTX_free(vhost->ssl_client_ctx);
-#endif
-#endif
-	}
 }
 
 void
 lws_ssl_context_destroy(struct lws_context *context)
 {
-#if defined(LWS_USE_POLARSSL)
-#else
-#if defined(LWS_USE_MBEDTLS)
-#else
-#if (OPENSSL_VERSION_NUMBER < 0x10100006L)
-#if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_WOLFSSL)
+
+// after 1.1.0 no need
+#if (OPENSSL_VERSION_NUMBER <  0x10100000)
+// <= 1.0.1f = old api, 1.0.1g+ = new api
+#if (OPENSSL_VERSION_NUMBER <= 0x1000106f) || defined(USE_WOLFSSL)
 	ERR_remove_state(0);
 #else
-#if (OPENSSL_VERSION_NUMBER >= 0x10100005L) && \
-	!defined(LIBRESSL_VERSION_NUMBER) && \
-	!defined(OPENSSL_IS_BORINGSSL)
+#if OPENSSL_VERSION_NUMBER >= 0x1010005f && \
+    !defined(LIBRESSL_VERSION_NUMBER) && \
+    !defined(OPENSSL_IS_BORINGSSL)
 	ERR_remove_thread_state();
 #else
 	ERR_remove_thread_state(NULL);
@@ -708,6 +613,4 @@ lws_ssl_context_destroy(struct lws_context *context)
 	EVP_cleanup();
 	CRYPTO_cleanup_all_ex_data();
 #endif
-#endif
-#endif
 }

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/libwebsockets.dox → EVSE/GPL/libwebsockets-2.2.2-stable-org/libwebsockets.dox


+ 10 - 2
EVSE/GPL/libwebsockets-v2.1-stable/libwebsockets.spec → EVSE/GPL/libwebsockets-2.2.2-stable-org/libwebsockets.spec

@@ -1,5 +1,5 @@
 Name: libwebsockets
-Version: 2.1.0
+Version: 2.2.2
 Release: 1%{?dist}
 Summary: Websocket Server and Client Library
 
@@ -55,11 +55,13 @@ rm -rf $RPM_BUILD_ROOT
 /usr/bin/libwebsockets-test-echo
 /usr/bin/libwebsockets-test-fraggle
 /usr/bin/libwebsockets-test-fuzxy
-/%{_libdir}/libwebsockets.so.8
+/%{_libdir}/libwebsockets.so.10
 /%{_libdir}/libwebsockets.so
 /%{_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,12 @@ 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
+
 * Thu Oct 06 2016 Andy Green <andy@warmcat.com> 2.1.0-1
 - MAJOR SONAMEBUMP APICHANGES Upstream 2.1.0 release
 

+ 19 - 0
EVSE/GPL/libwebsockets-v2.1-stable/lws_config.h.in → EVSE/GPL/libwebsockets-2.2.2-stable-org/lws_config.h.in

@@ -15,10 +15,12 @@
 /* Also define to 1 (in addition to USE_WOLFSSL) when using the
   (older) CyaSSL library */
 #cmakedefine USE_OLD_CYASSL
+#cmakedefine LWS_USE_BORINGSSL
 
 #cmakedefine LWS_USE_MBEDTLS
 #cmakedefine LWS_USE_POLARSSL
 #cmakedefine LWS_WITH_ESP8266
+#cmakedefine LWS_WITH_ESP32
 
 #cmakedefine LWS_WITH_PLUGINS
 #cmakedefine LWS_WITH_NO_LOGS
@@ -99,6 +101,9 @@
 /* HTTP Proxy support */
 #cmakedefine LWS_WITH_HTTP_PROXY
 
+/* HTTP Ranges support */
+#cmakedefine LWS_WITH_RANGES
+
 /* Http access log support */
 #cmakedefine LWS_WITH_ACCESS_LOG
 #cmakedefine LWS_WITH_SERVER_STATUS
@@ -114,4 +119,18 @@
 /* SMTP */
 #cmakedefine LWS_WITH_SMTP
 
+/* OPTEE */
+#cmakedefine LWS_PLAT_OPTEE
+
+/* ZIP FOPS */
+#cmakedefine LWS_WITH_ZIP_FOPS
+#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}

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lws_config_private.h.in → EVSE/GPL/libwebsockets-2.2.2-stable-org/lws_config_private.h.in


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lwsws/etc-logrotate.d-lwsws → EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/etc-logrotate.d-lwsws


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lwsws/etc-lwsws-conf-EXAMPLE → EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/etc-lwsws-conf-EXAMPLE


+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lwsws/etc-lwsws-conf.d-localhost-EXAMPLE → EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/etc-lwsws-conf.d-localhost-EXAMPLE


+ 184 - 82
EVSE/GPL/libwebsockets-v2.1-stable-org/lwsws/main.c → EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/main.c

@@ -32,14 +32,28 @@
 #include <syslog.h>
 #include <sys/time.h>
 #include <unistd.h>
+#include <sys/wait.h>
 #else
 #include <io.h>
 #include "gettimeofday.h"
+
+int fork(void)
+{
+	fprintf(stderr, "Sorry Windows doesn't support fork().\n");
+	return 0;
+}
 #endif
 
 #include "../lib/libwebsockets.h"
 
+#include <uv.h>
+
 static struct lws_context *context;
+static char config_dir[128];
+static int opts = 0, do_reload = 1;
+static uv_loop_t loop;
+static uv_signal_t signal_outer;
+static int pids[32];
 
 #define LWSWS_CONFIG_STRING_SIZE (32 * 1024)
 
@@ -61,59 +75,141 @@ static struct option options[] = {
 	{ "help",	no_argument,		NULL, 'h' },
 	{ "debug",	required_argument,	NULL, 'd' },
 	{ "configdir",  required_argument,	NULL, 'c' },
-#ifndef LWS_NO_DAEMONIZE
-	{ "daemonize", 	no_argument,		NULL, 'D' },
-#endif
 	{ NULL, 0, 0, 0 }
 };
 
 void signal_cb(uv_signal_t *watcher, int signum)
 {
-	lwsl_err("Signal %d caught, exiting...\n", watcher->signum);
 	switch (watcher->signum) {
 	case SIGTERM:
 	case SIGINT:
 		break;
+
+	case SIGHUP:
+		if (lws_context_is_deprecated(context))
+			return;
+		lwsl_notice("Dropping listen sockets\n");
+		lws_context_deprecate(context, NULL);
+		return;
+
 	default:
 		signal(SIGABRT, SIG_DFL);
 		abort();
 		break;
 	}
+	lwsl_err("Signal %d caught\n", watcher->signum);
 	lws_libuv_stop(context);
 }
 
-int main(int argc, char **argv)
+static int
+context_creation(void)
 {
+	int cs_len = LWSWS_CONFIG_STRING_SIZE - 1;
 	struct lws_context_creation_info info;
-	char *cs;
-	int opts = 0, cs_len = LWSWS_CONFIG_STRING_SIZE - 1;
-	int n = 0;
+	char *cs, *config_strings;
+
+	cs = config_strings = malloc(LWSWS_CONFIG_STRING_SIZE);
+	if (!config_strings) {
+		lwsl_err("Unable to allocate config strings heap\n");
+		return -1;
+	}
+
+	memset(&info, 0, sizeof(info));
+
+	info.external_baggage_free_on_destroy = config_strings;
+	info.max_http_header_pool = 16;
+	info.options = opts | LWS_SERVER_OPTION_VALIDATE_UTF8 |
+			      LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
+			      LWS_SERVER_OPTION_LIBUV;
+
+	info.plugin_dirs = plugin_dirs;
+	lwsl_notice("Using config dir: \"%s\"\n", config_dir);
+
+	/*
+	 *  first go through the config for creating the outer context
+	 */
+	if (lwsws_get_config_globals(&info, config_dir, &cs, &cs_len))
+		goto init_failed;
+
+	context = lws_create_context(&info);
+	if (context == NULL) {
+		lwsl_err("libwebsocket init failed\n");
+		goto init_failed;
+	}
+
+	lws_uv_sigint_cfg(context, 1, signal_cb);
+	lws_uv_initloop(context, &loop, 0);
+
+	/*
+	 * then create the vhosts... protocols are entirely coming from
+	 * plugins, so we leave it NULL
+	 */
+
+	info.extensions = exts;
+
+	if (lwsws_get_config_vhosts(context, &info, config_dir,
+				    &cs, &cs_len))
+		return 1;
+
+	return 0;
+
+init_failed:
+	free(config_strings);
+
+	return 1;
+}
+
+
+/*
+ * root-level sighup handler
+ */
+
+static void
+reload_handler(int signum)
+{
 #ifndef _WIN32
-	int syslog_options = LOG_PID | LOG_PERROR;
+	int m;
+
+	switch (signum) {
+
+	case SIGHUP: /* reload */
+		fprintf(stderr, "root process receives reload\n");
+		if (!do_reload) {
+			fprintf(stderr, "passing HUP to child processes\n");
+			for (m = 0; m < ARRAY_SIZE(pids); m++)
+				if (pids[m])
+					kill(pids[m], SIGHUP);
+			sleep(1);
+		}
+		do_reload = 1;
+		break;
+	case SIGINT:
+	case SIGTERM:
+	case SIGKILL:
+		fprintf(stderr, "killing service processes\n");
+		for (m = 0; m < ARRAY_SIZE(pids); m++)
+			if (pids[m])
+				kill(pids[m], SIGTERM);
+		exit(0);
+	}
+#else
+	// kill() implementation needed for WIN32
 #endif
-#ifndef LWS_NO_DAEMONIZE
- 	int daemonize = 0;
+}
+
+int main(int argc, char **argv)
+{
+	int n = 0, m, debug_level = 7;
+#ifndef _WIN32
+	int status, syslog_options = LOG_PID | LOG_PERROR;
 #endif
-	int debug_level = 7;
-	char config_dir[128];
-	char *config_strings;
 
-	memset(&info, 0, sizeof info);
 	strcpy(config_dir, "/etc/lwsws");
 	while (n >= 0) {
-		n = getopt_long(argc, argv, "hd:c:D", options, NULL);
+		n = getopt_long(argc, argv, "hd:c:", options, NULL);
 		if (n < 0)
 			continue;
 		switch (n) {
-#ifndef LWS_NO_DAEMONIZE
-		case 'D':
-			daemonize = 1;
-			#ifndef _WIN32
-			syslog_options &= ~LOG_PERROR;
-			#endif
-			printf("Daemonizing...\n");
-			break;
-#endif
 		case 'd':
 			debug_level = atoi(optarg);
 			break;
@@ -127,20 +223,52 @@ int main(int argc, char **argv)
 			exit(1);
 		}
 	}
-
-#if !defined(LWS_NO_DAEMONIZE) && !defined(WIN32)
+#ifndef _WIN32
 	/*
-	 * normally lock path would be /var/lock/lwsts or similar, to
-	 * simplify getting started without having to take care about
-	 * permissions or running as root, set to /tmp/.lwsts-lock
+	 * We leave our original process up permanently, because that
+	 * suits systemd.
+	 *
+	 * Otherwise we get into problems when reload spawns new processes and
+	 * the original one dies randomly.
 	 */
-	if (daemonize && lws_daemonize("/tmp/.lwsts-lock")) {
-		fprintf(stderr, "Failed to daemonize\n");
-		return 10;
+
+	signal(SIGHUP, reload_handler);
+	signal(SIGINT, reload_handler);
+
+	fprintf(stderr, "Root process is %u\n", getpid());
+
+	while (1) {
+		if (do_reload) {
+			do_reload = 0;
+			n = fork();
+			if (n == 0) /* new */
+				break;
+			/* old */
+			if (n > 0)
+				for (m = 0; m < ARRAY_SIZE(pids); m++)
+					if (!pids[m]) {
+						// fprintf(stderr, "added child pid %d\n", n);
+						pids[m] = n;
+						break;
+					}
+		}
+#ifndef _WIN32
+		sleep(2);
+
+		n = waitpid(-1, &status, WNOHANG);
+		if (n > 0)
+			for (m = 0; m < ARRAY_SIZE(pids); m++)
+				if (pids[m] == n) {
+					// fprintf(stderr, "reaped child pid %d\n", pids[m]);
+					pids[m] = 0;
+					break;
+				}
+#else
+// !!! implemenation needed
+#endif
 	}
-	if (daemonize)
-		lwsl_notice("Daemonized\n");
 #endif
+	/* child process */
 
 #ifndef _WIN32
 	/* we will only try to log things according to our debug_level */
@@ -153,54 +281,33 @@ int main(int argc, char **argv)
 	lwsl_notice("lwsws libwebsockets web server - license CC0 + LGPL2.1\n");
 	lwsl_notice("(C) Copyright 2010-2016 Andy Green <andy@warmcat.com>\n");
 
-	cs = config_strings = malloc(LWSWS_CONFIG_STRING_SIZE);
-	if (!config_strings) {
-		lwsl_err("Unable to allocate config strings heap\n");
-		return -1;
-	}
-
-	memset(&info, 0, sizeof(info));
-
-	info.max_http_header_pool = 16;
-	info.options = opts | LWS_SERVER_OPTION_VALIDATE_UTF8 |
-			      LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
-			      LWS_SERVER_OPTION_LIBUV;
-
-	info.plugin_dirs = plugin_dirs;
-	lwsl_notice("Using config dir: \"%s\"\n", config_dir);
-
-	/*
-	 *  first go through the config for creating the outer context
-	 */
-	if (lwsws_get_config_globals(&info, config_dir, &cs, &cs_len))
-		goto init_failed;
+#if (UV_VERSION_MAJOR > 0) // Travis...
+	uv_loop_init(&loop);
+#else
+	fprintf(stderr, "Your libuv is too old!\n");
+	return 0;
+#endif
+	uv_signal_init(&loop, &signal_outer);
+	uv_signal_start(&signal_outer, signal_cb, SIGINT);
+	uv_signal_start(&signal_outer, signal_cb, SIGHUP);
 
-	context = lws_create_context(&info);
-	if (context == NULL) {
-		lwsl_err("libwebsocket init failed\n");
-		goto init_failed;
+	if (context_creation()) {
+		lwsl_err("Context creation failed\n");
+		return 1;
 	}
 
-	/*
-	 * then create the vhosts... protocols are entirely coming from
-	 * plugins, so we leave it NULL
-	 */
-
-	info.extensions = exts;
-
-	if (!lwsws_get_config_vhosts(context, &info, config_dir,
-				     &cs, &cs_len)) {
+	lws_libuv_run(context, 0);
 
-		/* run the server */
+	uv_signal_stop(&signal_outer);
+	lws_context_destroy(context);
 
-		lws_uv_sigint_cfg(context, 1, signal_cb);
-		lws_uv_initloop(context, NULL, 0);
+#if (UV_VERSION_MAJOR > 0) // Travis...
+	n = 0;
+	while (n++ < 1024 && uv_loop_close(&loop))
+		uv_run(&loop, UV_RUN_NOWAIT);
+#endif
 
-		lws_libuv_run(context, 0);
-	}
-
-	lws_context_destroy(context);
-	free(config_strings);
+	lws_context_destroy2(context);
 
 	fprintf(stderr, "lwsws exited cleanly\n");
 
@@ -209,9 +316,4 @@ int main(int argc, char **argv)
 #endif
 
 	return 0;
-
-init_failed:
-	free(config_strings);
-
-	return 1;
 }

+ 2 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/lwsws/usr-lib-systemd-system-lwsws.service → EVSE/GPL/libwebsockets-2.2.2-stable-org/lwsws/usr-lib-systemd-system-lwsws.service

@@ -4,6 +4,8 @@ After=syslog.target
 
 [Service]
 ExecStart=/usr/local/bin/lwsws
+ExecReload=/usr/bin/kill -HUP $MAINPID
+ExecStop=/usr/bin/killall lwsws
 StandardError=null
 
 [Install]

+ 4 - 1
EVSE/GPL/libwebsockets-v2.1-stable/mainpage.md → EVSE/GPL/libwebsockets-2.2.2-stable-org/mainpage.md

@@ -10,4 +10,7 @@ Libwebsockets covers a lot of interesting features for people making embedded se
  - account management (including registration, email verification, lost pw etc)
  - strong ssl PFS support (A+ on SSLlabs test)
 
-You can browse by api category <a href="modules.html">here</a>.
+You can browse by api category <a href="modules.html">here</a>
+
+A collection of READMEs for build, coding, lwsws etc are <a href="pages.html">here</a>
+

+ 0 - 0
EVSE/GPL/libwebsockets-v2.1-stable-org/module.json → EVSE/GPL/libwebsockets-2.2.2-stable-org/module.json


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است