SET(LWS_WITH_EXTERNAL_POLL ON CACHE BOOL "" FORCE)
SET(LWS_IPV6 ON CACHE BOOL "" FORCE)
SET(LWS_WITHOUT_TESTAPPS ON CACHE BOOL "" FORCE)
+ SET(LWS_WITH_FILE_OPS OFF CACHE BOOL "" FORCE)
SET(LWS_WITH_VINE_EXT ON CACHE BOOL "" FORCE)
ADD_SUBDIRECTORY(third-party/libwebsockets)
ENDIF(NOT USE_LIBWEBSOCKETS_STATIC_PREBUILT)
%bcond_without lws_static_prebuilt
Name: capi-network-vine
Summary: An service discovery framework
-Version: 1.0.6
+Version: 1.0.7
Release: 0
Group: Network & Connectivity/API
License: Apache-2.0
#endif
#endif
-#define LWS_INSTALL_DATADIR "./share"
+#define LWS_INSTALL_DATADIR "/usr/local/share"
+#define LWS_INSTALL_LIBDIR "/usr/local/lib"
#define LWS_LIBRARY_VERSION_MAJOR 4
-#define LWS_LIBRARY_VERSION_MINOR 0
-#define LWS_LIBRARY_VERSION_PATCH 22
+#define LWS_LIBRARY_VERSION_MINOR 2
+#define LWS_LIBRARY_VERSION_PATCH_ELABORATED 0-accepted/tizen/unified/20210602.122354-9-g8ca7310
+#define LWS_LIBRARY_VERSION_PATCH 0
+
/* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */
#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR * 1000000) + \
(LWS_LIBRARY_VERSION_MINOR * 1000) + \
LWS_LIBRARY_VERSION_PATCH
#define LWS_MAX_SMP 1
+/* #undef LWS_ESP_PLATFORM */
/* #undef LWS_LIBRARY_VERSION_NUMBER */
+/* #undef LWS_EXT_PTHREAD_LIBRARIES */
+
/* #undef LWS_AVOID_SIGPIPE_IGN */
-#define LWS_BUILD_HASH "e87a691"
+#define LWS_BUILD_HASH "accepted/tizen/unified/20210602.122354-9-g8ca7310"
/* #undef LWS_BUILTIN_GETIFADDRS */
#define LWS_CLIENT_HTTP_PROXYING
/* #undef LWS_DETECTED_PLAT_IOS */
#define LWS_HAVE_BN_bn2binpad
#define LWS_HAVE_CLOCK_GETTIME
#define LWS_HAVE_EC_POINT_get_affine_coordinates
+#define LWS_HAVE_EC_KEY_new_by_curve_name
#define LWS_HAVE_ECDSA_SIG_set0
#define LWS_HAVE_EVP_MD_CTX_free
#define LWS_HAVE_EVP_aes_128_wrap
#define LWS_HAVE_EVP_aes_256_cfb8
#define LWS_HAVE_EVP_aes_256_cfb128
#define LWS_HAVE_EVP_aes_128_xts
+#define LWS_HAVE_EVP_PKEY_new_raw_private_key
#define LWS_HAVE_EXECVPE
+#define LWS_HAVE_LOCALTIME_R
+#define LWS_HAVE_GMTIME_R
+#define LWS_HAVE_CTIME_R
+#define LWS_HAVE_GETGRGID_R
+#define LWS_HAVE_GETGRNAM_R
+#define LWS_HAVE_GETPWUID_R
+#define LWS_HAVE_GETPWNAM_R
/* #undef LWS_HAVE_LIBCAP */
#define LWS_HAVE_HMAC_CTX_new
#define LWS_HAVE_MALLOC_H
-/* #undef LWS_HAVE_MALLOC_TRIM */
+#define LWS_HAVE_MALLOC_TRIM
#define LWS_HAVE_MALLOC_USABLE_SIZE
+/* #undef LWS_HAVE_mbedtls_md_setup */
/* #undef LWS_HAVE_mbedtls_net_init */
+/* #undef LWS_HAVE_mbedtls_rsa_complete */
+/* #undef LWS_HAVE_mbedtls_internal_aes_encrypt */
/* #undef LWS_HAVE_mbedtls_ssl_conf_alpn_protocols */
/* #undef LWS_HAVE_mbedtls_ssl_get_alpn_protocol */
/* #undef LWS_HAVE_mbedtls_ssl_conf_sni */
#define LWS_HAVE_RSA_SET0_KEY
/* #undef LWS_HAVE_RSA_verify_pss_mgf1 */
#define LWS_HAVE_SSL_CTX_get0_certificate
+/* #undef LWS_HAVE_SSL_CTX_load_verify_file */
+/* #undef LWS_HAVE_SSL_CTX_load_verify_dir */
#define LWS_HAVE_SSL_CTX_set1_param
-#define LWS_HAVE_SSL_CTX_set_ciphersuites
+/* #undef LWS_HAVE_SSL_CTX_set_ciphersuites */
#define LWS_HAVE_SSL_EXTRA_CHAIN_CERTS
#define LWS_HAVE_SSL_get0_alpn_selected
#define LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key
#define LWS_HAVE_SSL_set_alpn_protos
#define LWS_HAVE_SSL_SET_INFO_CALLBACK
+#define LWS_HAVE_SSL_SESSION_set_time
+/* #undef LWS_HAVE_SSL_SESSION_up_ref */
/* #undef LWS_HAVE__STAT32I64 */
#define LWS_HAVE_STDINT_H
-#define LWS_HAVE_SYS_CAPABILITY_H
+/* #undef LWS_HAVE_SYS_CAPABILITY_H */
#define LWS_HAVE_TLS_CLIENT_METHOD
#define LWS_HAVE_TLSV1_2_CLIENT_METHOD
+#define LWS_HAVE_SUSECONDS_T
/* #undef LWS_HAVE_UV_VERSION_H */
#define LWS_HAVE_VFORK
#define LWS_HAVE_X509_get_key_usage
#define LWS_HAVE_X509_VERIFY_PARAM_set1_host
-#define LWS_LIBRARY_VERSION "4.0.22"
+#define LWS_LIBRARY_VERSION "4.2.0-accepted/tizen/unified/20210602.122354-9-g8ca7310"
#define LWS_LOGGING_BITFIELD_CLEAR 0
#define LWS_LOGGING_BITFIELD_SET 0
+#define LWS_LOG_TAG_LIFECYCLE
/* #undef LWS_MINGW_SUPPORT */
/* #undef LWS_NO_CLIENT */
#define LWS_NO_DAEMONIZE
/* #undef LWS_SHA1_USE_OPENSSL_NAME */
#define LWS_SSL_CLIENT_USE_OS_CA_CERTS
/* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */
+/* #undef LWS_SUPPRESS_DEPRECATED_API_WARNINGS */
+/* #undef LWS_TLS_LOG_PLAINTEXT_RX */
+/* #undef LWS_TLS_LOG_PLAINTEXT_TX */
/* #undef LWS_WITH_ABSTRACT */
/* #undef LWS_WITH_ACCESS_LOG */
/* #undef LWS_WITH_ACME */
/* #undef LWS_WITH_SYS_ASYNC_DNS */
/* #undef LWS_WITH_BORINGSSL */
/* #undef LWS_WITH_CGI */
+#define LWS_WITH_CONMON
#define LWS_WITH_CUSTOM_HEADERS
/* #undef LWS_WITH_DEPRECATED_LWS_DLL */
/* #undef LWS_WITH_DETAILED_LATENCY */
#define LWS_WITH_DIR
+/* #undef LWS_WITH_DRIVERS */
/* #undef LWS_WITH_ESP32 */
/* #undef LWS_HAVE_EVBACKEND_LINUXAIO */
/* #undef LWS_HAVE_EVBACKEND_IOURING */
#define LWS_WITH_EXTERNAL_POLL
-#define LWS_WITH_FILE_OPS
+/* #undef LWS_WITH_FILE_OPS */
/* #undef LWS_WITH_FSMOUNT */
/* #undef LWS_WITH_FTS */
/* #undef LWS_WITH_GENCRYPTO */
#define LWS_WITH_HTTP2
#define LWS_WITH_HTTP_BASIC_AUTH
/* #undef LWS_WITH_HTTP_BROTLI */
+/* #undef LWS_HTTP_HEADERS_ALL */
/* #undef LWS_WITH_HTTP_PROXY */
/* #undef LWS_WITH_HTTP_STREAM_COMPRESSION */
#define LWS_WITH_HTTP_UNCOMMON_HEADERS
/* #undef LWS_WITH_LIBEV */
/* #undef LWS_WITH_LIBEVENT */
/* #undef LWS_WITH_LIBUV */
+/* #undef LWS_WITH_SDEVENT */
#define LWS_WITH_LWSAC
#define LWS_LOGS_TIMESTAMP
/* #undef LWS_WITH_MBEDTLS */
/* #undef LWS_WITH_MINIZ */
+#define LWS_WITH_NETLINK
#define LWS_WITH_NETWORK
/* #undef LWS_WITH_NO_LOGS */
#define LWS_WITH_CLIENT
/* #undef LWS_WITH_SPAWN */
/* #undef LWS_WITH_PEER_LIMITS */
/* #undef LWS_WITH_PLUGINS */
+/* #undef LWS_WITH_PLUGINS_BUILTIN */
/* #undef LWS_WITH_POLARSSL */
#define LWS_WITH_POLL
/* #undef LWS_WITH_RANGES */
+/* #undef LWS_WITH_RFC6724 */
/* #undef LWS_WITH_SECURE_STREAMS */
+/* #undef LWS_WITH_SECURE_STREAMS_CPP */
/* #undef LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM */
/* #undef LWS_WITH_SECURE_STREAMS_PROXY_API */
+/* #undef LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY */
+/* #undef LWS_WITH_SECURE_STREAMS_AUTH_SIGV4 */
/* #undef LWS_WITH_SELFTESTS */
-#define LWS_WITH_SEQUENCER
+/* #undef LWS_WITH_SEQUENCER */
/* #undef LWS_WITH_SERVER_STATUS */
+#define LWS_WITH_SYS_SMD
/* #undef LWS_WITH_SMTP */
/* #undef LWS_WITH_SOCKS5 */
/* #undef LWS_WITH_STATEFUL_URLDECODE */
/* #undef LWS_WITH_STATS */
/* #undef LWS_WITH_STRUCT_SQLITE3 */
/* #undef LWS_WITH_STRUCT_JSON */
+/* #undef LWS_WITH_SUL_DEBUGGING */
/* #undef LWS_WITH_SQLITE3 */
-/* #undef LWS_WITH_SYS_NTPCLIENT */
/* #undef LWS_WITH_SYS_DHCP_CLIENT */
+/* #undef LWS_WITH_SYS_FAULT_INJECTION */
+/* #undef LWS_WITH_SYS_METRICS */
+/* #undef LWS_WITH_SYS_NTPCLIENT */
+#define LWS_WITH_SYS_STATE
/* #undef LWS_WITH_THREADPOOL */
#define LWS_WITH_TLS
+#define LWS_WITH_TLS_SESSIONS
#define LWS_WITH_UDP
-/* #undef LWS_WITH_UNIX_SOCK */
+/* #undef LWS_WITH_ULOOP */
+#define LWS_WITH_UNIX_SOCK
/* #undef LWS_WITH_ZIP_FOPS */
/* #undef USE_OLD_CYASSL */
/* #undef USE_WOLFSSL */
-
+/* #undef LWS_WITH_EVENT_LIBS */
+/* #undef LWS_WITH_EVLIB_PLUGINS */
+/* #undef LWS_WITH_LIBUV_INTERNAL */
+/* #undef LWS_WITH_PLUGINS_API */
+#define LWS_HAVE_RTA_PREF
#endif
#endif
-#define LWS_INSTALL_DATADIR "./share"
+#define LWS_INSTALL_DATADIR "/usr/local/share"
+#define LWS_INSTALL_LIBDIR "/usr/local/lib"
#define LWS_LIBRARY_VERSION_MAJOR 4
-#define LWS_LIBRARY_VERSION_MINOR 0
-#define LWS_LIBRARY_VERSION_PATCH 22
+#define LWS_LIBRARY_VERSION_MINOR 2
+#define LWS_LIBRARY_VERSION_PATCH_ELABORATED 0-accepted/tizen/unified/20210602.122354-9-g8ca7310
+#define LWS_LIBRARY_VERSION_PATCH 0
+
/* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */
#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR * 1000000) + \
(LWS_LIBRARY_VERSION_MINOR * 1000) + \
LWS_LIBRARY_VERSION_PATCH
#define LWS_MAX_SMP 1
+/* #undef LWS_ESP_PLATFORM */
/* #undef LWS_LIBRARY_VERSION_NUMBER */
+/* #undef LWS_EXT_PTHREAD_LIBRARIES */
+
/* #undef LWS_AVOID_SIGPIPE_IGN */
-#define LWS_BUILD_HASH "c43e5fc"
+#define LWS_BUILD_HASH "accepted/tizen/unified/20210602.122354-9-g8ca7310"
/* #undef LWS_BUILTIN_GETIFADDRS */
#define LWS_CLIENT_HTTP_PROXYING
/* #undef LWS_DETECTED_PLAT_IOS */
#define LWS_HAVE_BN_bn2binpad
#define LWS_HAVE_CLOCK_GETTIME
#define LWS_HAVE_EC_POINT_get_affine_coordinates
+#define LWS_HAVE_EC_KEY_new_by_curve_name
#define LWS_HAVE_ECDSA_SIG_set0
#define LWS_HAVE_EVP_MD_CTX_free
#define LWS_HAVE_EVP_aes_128_wrap
#define LWS_HAVE_EVP_aes_256_cfb8
#define LWS_HAVE_EVP_aes_256_cfb128
#define LWS_HAVE_EVP_aes_128_xts
+#define LWS_HAVE_EVP_PKEY_new_raw_private_key
#define LWS_HAVE_EXECVPE
+#define LWS_HAVE_LOCALTIME_R
+#define LWS_HAVE_GMTIME_R
+#define LWS_HAVE_CTIME_R
+#define LWS_HAVE_GETGRGID_R
+#define LWS_HAVE_GETGRNAM_R
+#define LWS_HAVE_GETPWUID_R
+#define LWS_HAVE_GETPWNAM_R
/* #undef LWS_HAVE_LIBCAP */
#define LWS_HAVE_HMAC_CTX_new
#define LWS_HAVE_MALLOC_H
-/* #undef LWS_HAVE_MALLOC_TRIM */
+#define LWS_HAVE_MALLOC_TRIM
#define LWS_HAVE_MALLOC_USABLE_SIZE
+/* #undef LWS_HAVE_mbedtls_md_setup */
/* #undef LWS_HAVE_mbedtls_net_init */
+/* #undef LWS_HAVE_mbedtls_rsa_complete */
+/* #undef LWS_HAVE_mbedtls_internal_aes_encrypt */
/* #undef LWS_HAVE_mbedtls_ssl_conf_alpn_protocols */
/* #undef LWS_HAVE_mbedtls_ssl_get_alpn_protocol */
/* #undef LWS_HAVE_mbedtls_ssl_conf_sni */
#define LWS_HAVE_RSA_SET0_KEY
/* #undef LWS_HAVE_RSA_verify_pss_mgf1 */
#define LWS_HAVE_SSL_CTX_get0_certificate
+/* #undef LWS_HAVE_SSL_CTX_load_verify_file */
+/* #undef LWS_HAVE_SSL_CTX_load_verify_dir */
#define LWS_HAVE_SSL_CTX_set1_param
-#define LWS_HAVE_SSL_CTX_set_ciphersuites
+/* #undef LWS_HAVE_SSL_CTX_set_ciphersuites */
#define LWS_HAVE_SSL_EXTRA_CHAIN_CERTS
#define LWS_HAVE_SSL_get0_alpn_selected
#define LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key
#define LWS_HAVE_SSL_set_alpn_protos
#define LWS_HAVE_SSL_SET_INFO_CALLBACK
+#define LWS_HAVE_SSL_SESSION_set_time
+/* #undef LWS_HAVE_SSL_SESSION_up_ref */
/* #undef LWS_HAVE__STAT32I64 */
#define LWS_HAVE_STDINT_H
-#define LWS_HAVE_SYS_CAPABILITY_H
+/* #undef LWS_HAVE_SYS_CAPABILITY_H */
#define LWS_HAVE_TLS_CLIENT_METHOD
#define LWS_HAVE_TLSV1_2_CLIENT_METHOD
+#define LWS_HAVE_SUSECONDS_T
/* #undef LWS_HAVE_UV_VERSION_H */
#define LWS_HAVE_VFORK
#define LWS_HAVE_X509_get_key_usage
#define LWS_HAVE_X509_VERIFY_PARAM_set1_host
-#define LWS_LIBRARY_VERSION "4.0.22"
+#define LWS_LIBRARY_VERSION "4.2.0-accepted/tizen/unified/20210602.122354-9-g8ca7310"
#define LWS_LOGGING_BITFIELD_CLEAR 0
#define LWS_LOGGING_BITFIELD_SET 0
+#define LWS_LOG_TAG_LIFECYCLE
/* #undef LWS_MINGW_SUPPORT */
/* #undef LWS_NO_CLIENT */
#define LWS_NO_DAEMONIZE
/* #undef LWS_SHA1_USE_OPENSSL_NAME */
#define LWS_SSL_CLIENT_USE_OS_CA_CERTS
/* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */
+/* #undef LWS_SUPPRESS_DEPRECATED_API_WARNINGS */
+/* #undef LWS_TLS_LOG_PLAINTEXT_RX */
+/* #undef LWS_TLS_LOG_PLAINTEXT_TX */
/* #undef LWS_WITH_ABSTRACT */
/* #undef LWS_WITH_ACCESS_LOG */
/* #undef LWS_WITH_ACME */
/* #undef LWS_WITH_SYS_ASYNC_DNS */
/* #undef LWS_WITH_BORINGSSL */
/* #undef LWS_WITH_CGI */
+#define LWS_WITH_CONMON
#define LWS_WITH_CUSTOM_HEADERS
/* #undef LWS_WITH_DEPRECATED_LWS_DLL */
/* #undef LWS_WITH_DETAILED_LATENCY */
#define LWS_WITH_DIR
+/* #undef LWS_WITH_DRIVERS */
/* #undef LWS_WITH_ESP32 */
/* #undef LWS_HAVE_EVBACKEND_LINUXAIO */
/* #undef LWS_HAVE_EVBACKEND_IOURING */
#define LWS_WITH_EXTERNAL_POLL
-#define LWS_WITH_FILE_OPS
+/* #undef LWS_WITH_FILE_OPS */
/* #undef LWS_WITH_FSMOUNT */
/* #undef LWS_WITH_FTS */
/* #undef LWS_WITH_GENCRYPTO */
#define LWS_WITH_HTTP2
#define LWS_WITH_HTTP_BASIC_AUTH
/* #undef LWS_WITH_HTTP_BROTLI */
+/* #undef LWS_HTTP_HEADERS_ALL */
/* #undef LWS_WITH_HTTP_PROXY */
/* #undef LWS_WITH_HTTP_STREAM_COMPRESSION */
#define LWS_WITH_HTTP_UNCOMMON_HEADERS
/* #undef LWS_WITH_LIBEV */
/* #undef LWS_WITH_LIBEVENT */
/* #undef LWS_WITH_LIBUV */
+/* #undef LWS_WITH_SDEVENT */
#define LWS_WITH_LWSAC
#define LWS_LOGS_TIMESTAMP
/* #undef LWS_WITH_MBEDTLS */
/* #undef LWS_WITH_MINIZ */
+#define LWS_WITH_NETLINK
#define LWS_WITH_NETWORK
/* #undef LWS_WITH_NO_LOGS */
#define LWS_WITH_CLIENT
/* #undef LWS_WITH_SPAWN */
/* #undef LWS_WITH_PEER_LIMITS */
/* #undef LWS_WITH_PLUGINS */
+/* #undef LWS_WITH_PLUGINS_BUILTIN */
/* #undef LWS_WITH_POLARSSL */
#define LWS_WITH_POLL
/* #undef LWS_WITH_RANGES */
+/* #undef LWS_WITH_RFC6724 */
/* #undef LWS_WITH_SECURE_STREAMS */
+/* #undef LWS_WITH_SECURE_STREAMS_CPP */
/* #undef LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM */
/* #undef LWS_WITH_SECURE_STREAMS_PROXY_API */
+/* #undef LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY */
+/* #undef LWS_WITH_SECURE_STREAMS_AUTH_SIGV4 */
/* #undef LWS_WITH_SELFTESTS */
-#define LWS_WITH_SEQUENCER
+/* #undef LWS_WITH_SEQUENCER */
/* #undef LWS_WITH_SERVER_STATUS */
+#define LWS_WITH_SYS_SMD
/* #undef LWS_WITH_SMTP */
/* #undef LWS_WITH_SOCKS5 */
/* #undef LWS_WITH_STATEFUL_URLDECODE */
/* #undef LWS_WITH_STATS */
/* #undef LWS_WITH_STRUCT_SQLITE3 */
/* #undef LWS_WITH_STRUCT_JSON */
+/* #undef LWS_WITH_SUL_DEBUGGING */
/* #undef LWS_WITH_SQLITE3 */
-/* #undef LWS_WITH_SYS_NTPCLIENT */
/* #undef LWS_WITH_SYS_DHCP_CLIENT */
+/* #undef LWS_WITH_SYS_FAULT_INJECTION */
+/* #undef LWS_WITH_SYS_METRICS */
+/* #undef LWS_WITH_SYS_NTPCLIENT */
+#define LWS_WITH_SYS_STATE
/* #undef LWS_WITH_THREADPOOL */
#define LWS_WITH_TLS
+#define LWS_WITH_TLS_SESSIONS
#define LWS_WITH_UDP
-/* #undef LWS_WITH_UNIX_SOCK */
+/* #undef LWS_WITH_ULOOP */
+#define LWS_WITH_UNIX_SOCK
/* #undef LWS_WITH_ZIP_FOPS */
/* #undef USE_OLD_CYASSL */
/* #undef USE_WOLFSSL */
-
+/* #undef LWS_WITH_EVENT_LIBS */
+/* #undef LWS_WITH_EVLIB_PLUGINS */
+/* #undef LWS_WITH_LIBUV_INTERNAL */
+/* #undef LWS_WITH_PLUGINS_API */
+#define LWS_HAVE_RTA_PREF
+++ /dev/null
-/* lws_config.h Generated from lws_config.h.in */
-
-#ifndef NDEBUG
- #ifndef _DEBUG
- #define _DEBUG
- #endif
-#endif
-
-#define LWS_INSTALL_DATADIR "/usr/local/share"
-#define LWS_LIBRARY_VERSION_MAJOR 4
-#define LWS_LIBRARY_VERSION_MINOR 0
-#define LWS_LIBRARY_VERSION_PATCH 22
-/* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */
-#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR * 1000000) + \
- (LWS_LIBRARY_VERSION_MINOR * 1000) + \
- LWS_LIBRARY_VERSION_PATCH
-#define LWS_MAX_SMP 1
-
-/* #undef LWS_LIBRARY_VERSION_NUMBER */
-
-/* #undef LWS_AVOID_SIGPIPE_IGN */
-#define LWS_BUILD_HASH "d85b58c"
-/* #undef LWS_BUILTIN_GETIFADDRS */
-#define LWS_CLIENT_HTTP_PROXYING
-/* #undef LWS_DETECTED_PLAT_IOS */
-/* #undef LWS_FALLBACK_GETHOSTBYNAME */
-#define LWS_HAS_INTPTR_T
-#define LWS_HAS_GETOPT_LONG
-/* #undef LWS_HAVE__ATOI64 */
-#define LWS_HAVE_ATOLL
-#define LWS_HAVE_BN_bn2binpad
-#define LWS_HAVE_CLOCK_GETTIME
-#define LWS_HAVE_EC_POINT_get_affine_coordinates
-#define LWS_HAVE_ECDSA_SIG_set0
-#define LWS_HAVE_EVP_MD_CTX_free
-#define LWS_HAVE_EVP_aes_128_wrap
-#define LWS_HAVE_EVP_aes_128_cfb8
-#define LWS_HAVE_EVP_aes_128_cfb128
-#define LWS_HAVE_EVP_aes_192_cfb8
-#define LWS_HAVE_EVP_aes_192_cfb128
-#define LWS_HAVE_EVP_aes_256_cfb8
-#define LWS_HAVE_EVP_aes_256_cfb128
-#define LWS_HAVE_EVP_aes_128_xts
-#define LWS_HAVE_EXECVPE
-/* #undef LWS_HAVE_LIBCAP */
-#define LWS_HAVE_HMAC_CTX_new
-#define LWS_HAVE_MALLOC_H
-#define LWS_HAVE_MALLOC_TRIM
-#define LWS_HAVE_MALLOC_USABLE_SIZE
-/* #undef LWS_HAVE_mbedtls_net_init */
-/* #undef LWS_HAVE_mbedtls_ssl_conf_alpn_protocols */
-/* #undef LWS_HAVE_mbedtls_ssl_get_alpn_protocol */
-/* #undef LWS_HAVE_mbedtls_ssl_conf_sni */
-/* #undef LWS_HAVE_mbedtls_ssl_set_hs_ca_chain */
-/* #undef LWS_HAVE_mbedtls_ssl_set_hs_own_cert */
-/* #undef LWS_HAVE_mbedtls_ssl_set_hs_authmode */
-/* #undef LWS_HAVE_MBEDTLS_NET_SOCKETS */
-/* #undef LWS_HAVE_NEW_UV_VERSION_H */
-#define LWS_HAVE_OPENSSL_ECDH_H
-#define LWS_HAVE_PIPE2
-#define LWS_HAVE_EVENTFD
-#define LWS_HAVE_PTHREAD_H
-#define LWS_HAVE_RSA_SET0_KEY
-/* #undef LWS_HAVE_RSA_verify_pss_mgf1 */
-#define LWS_HAVE_SSL_CTX_get0_certificate
-#define LWS_HAVE_SSL_CTX_set1_param
-#define LWS_HAVE_SSL_CTX_set_ciphersuites
-#define LWS_HAVE_SSL_EXTRA_CHAIN_CERTS
-#define LWS_HAVE_SSL_get0_alpn_selected
-#define LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key
-#define LWS_HAVE_SSL_set_alpn_protos
-#define LWS_HAVE_SSL_SET_INFO_CALLBACK
-/* #undef LWS_HAVE__STAT32I64 */
-#define LWS_HAVE_STDINT_H
-/* #undef LWS_HAVE_SYS_CAPABILITY_H */
-#define LWS_HAVE_TLS_CLIENT_METHOD
-#define LWS_HAVE_TLSV1_2_CLIENT_METHOD
-/* #undef LWS_HAVE_UV_VERSION_H */
-#define LWS_HAVE_VFORK
-#define LWS_HAVE_X509_get_key_usage
-#define LWS_HAVE_X509_VERIFY_PARAM_set1_host
-#define LWS_LIBRARY_VERSION "4.0.22"
-#define LWS_LOGGING_BITFIELD_CLEAR 0
-#define LWS_LOGGING_BITFIELD_SET 0
-/* #undef LWS_MINGW_SUPPORT */
-/* #undef LWS_NO_CLIENT */
-#define LWS_NO_DAEMONIZE
-#define LWS_OPENSSL_CLIENT_CERTS "../share"
-#define LWS_OPENSSL_SUPPORT
-/* #undef LWS_PLAT_OPTEE */
-#define LWS_PLAT_UNIX
-/* #undef LWS_PLAT_FREERTOS */
-/* #undef LWS_ROLE_CGI */
-/* #undef LWS_ROLE_DBUS */
-#define LWS_ROLE_H1
-#define LWS_ROLE_H2
-#define LWS_ROLE_RAW
-#define LWS_ROLE_RAW_FILE
-/* #undef LWS_ROLE_RAW_PROXY */
-#define LWS_ROLE_WS
-/* #undef LWS_ROLE_MQTT */
-/* #undef LWS_SHA1_USE_OPENSSL_NAME */
-#define LWS_SSL_CLIENT_USE_OS_CA_CERTS
-/* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */
-/* #undef LWS_WITH_ABSTRACT */
-/* #undef LWS_WITH_ACCESS_LOG */
-/* #undef LWS_WITH_ACME */
-/* #undef LWS_WITH_ALSA */
-/* #undef LWS_WITH_SYS_ASYNC_DNS */
-/* #undef LWS_WITH_BORINGSSL */
-/* #undef LWS_WITH_CGI */
-#define LWS_WITH_CUSTOM_HEADERS
-/* #undef LWS_WITH_DEPRECATED_LWS_DLL */
-/* #undef LWS_WITH_DETAILED_LATENCY */
-#define LWS_WITH_DIR
-/* #undef LWS_WITH_ESP32 */
-/* #undef LWS_HAVE_EVBACKEND_LINUXAIO */
-/* #undef LWS_HAVE_EVBACKEND_IOURING */
-#define LWS_WITH_EXTERNAL_POLL
-#define LWS_WITH_FILE_OPS
-/* #undef LWS_WITH_FSMOUNT */
-/* #undef LWS_WITH_FTS */
-/* #undef LWS_WITH_GENCRYPTO */
-/* #undef LWS_WITH_GENERIC_SESSIONS */
-/* #undef LWS_WITH_GLIB */
-/* #undef LWS_WITH_GTK */
-#define LWS_WITH_HTTP2
-#define LWS_WITH_HTTP_BASIC_AUTH
-/* #undef LWS_WITH_HTTP_BROTLI */
-/* #undef LWS_WITH_HTTP_PROXY */
-/* #undef LWS_WITH_HTTP_STREAM_COMPRESSION */
-#define LWS_WITH_HTTP_UNCOMMON_HEADERS
-#define LWS_WITH_IPV6
-/* #undef LWS_WITH_JOSE */
-#define LWS_WITH_LEJP
-/* #undef LWS_WITH_LIBEV */
-/* #undef LWS_WITH_LIBEVENT */
-/* #undef LWS_WITH_LIBUV */
-#define LWS_WITH_LWSAC
-#define LWS_LOGS_TIMESTAMP
-/* #undef LWS_WITH_MBEDTLS */
-/* #undef LWS_WITH_MINIZ */
-#define LWS_WITH_NETWORK
-/* #undef LWS_WITH_NO_LOGS */
-#define LWS_WITH_CLIENT
-#define LWS_WITHOUT_EXTENSIONS
-#define LWS_WITH_SERVER
-/* #undef LWS_WITH_SPAWN */
-/* #undef LWS_WITH_PEER_LIMITS */
-/* #undef LWS_WITH_PLUGINS */
-/* #undef LWS_WITH_POLARSSL */
-#define LWS_WITH_POLL
-/* #undef LWS_WITH_RANGES */
-/* #undef LWS_WITH_SECURE_STREAMS */
-/* #undef LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM */
-/* #undef LWS_WITH_SECURE_STREAMS_PROXY_API */
-/* #undef LWS_WITH_SELFTESTS */
-#define LWS_WITH_SEQUENCER
-/* #undef LWS_WITH_SERVER_STATUS */
-/* #undef LWS_WITH_SMTP */
-/* #undef LWS_WITH_SOCKS5 */
-/* #undef LWS_WITH_STATEFUL_URLDECODE */
-/* #undef LWS_WITH_STATS */
-/* #undef LWS_WITH_STRUCT_SQLITE3 */
-/* #undef LWS_WITH_STRUCT_JSON */
-/* #undef LWS_WITH_SQLITE3 */
-/* #undef LWS_WITH_SYS_NTPCLIENT */
-/* #undef LWS_WITH_SYS_DHCP_CLIENT */
-/* #undef LWS_WITH_THREADPOOL */
-#define LWS_WITH_TLS
-#define LWS_WITH_UDP
-/* #undef LWS_WITH_UNIX_SOCK */
-/* #undef LWS_WITH_ZIP_FOPS */
-/* #undef USE_OLD_CYASSL */
-/* #undef USE_WOLFSSL */
-
-
#include "lws_config.h"
+#if defined(LWS_SUPPRESS_DEPRECATED_API_WARNINGS)
+#define OPENSSL_USE_DEPRECATED
+#endif
+
/* place for one-shot opaque forward references */
+typedef struct lws_context * lws_ctx_t;
struct lws_sequencer;
struct lws_dsh;
#define O_RDONLY _O_RDONLY
#endif
+typedef int uid_t;
+typedef int gid_t;
+typedef unsigned short sa_family_t;
+#if !defined(LWS_HAVE_SUSECONDS_T)
+typedef unsigned int useconds_t;
+typedef int suseconds_t;
+#endif
+
#define LWS_INLINE __inline
#define LWS_VISIBLE
#define LWS_WARN_UNUSED_RESULT
#define LWS_WARN_DEPRECATED
#define LWS_FORMAT(string_index)
-#if !defined(LWS_EXTERN)
+#if !defined(LWS_EXTERN) && defined(LWS_BUILDING_SHARED)
#ifdef LWS_DLL
#ifdef LWS_INTERNAL
#define LWS_EXTERN extern __declspec(dllexport)
#endif
#endif
+#if !defined(LWS_INTERNAL) && !defined(LWS_EXTERN)
+#define LWS_EXTERN
+#define LWS_VISIBLE
+#endif
+
+#if !defined(LWS_EXTERN)
+#define LWS_EXTERN
+#endif
+
#define LWS_INVALID_FILE INVALID_HANDLE_VALUE
#define LWS_SOCK_INVALID (INVALID_SOCKET)
#define LWS_O_RDONLY _O_RDONLY
#endif
#endif
+#if defined(__FreeBSD__)
+#include <sys/signal.h>
+#endif
#if defined(__GNUC__)
/* warn_unused_result attribute only supported by GCC 3.4 or later */
#define LWS_WARN_UNUSED_RESULT
#endif
+#if defined(LWS_BUILDING_SHARED)
+/* this is only set when we're building lws itself shared */
#define LWS_VISIBLE __attribute__((visibility("default")))
+#define LWS_EXTERN extern
+
+#else /* not shared */
+#if defined(WIN32) || defined(_WIN32) || defined(__MINGW32__)
+#define LWS_VISIBLE
+#define LWS_EXTERN extern
+#else
+/*
+ * If we explicitly say hidden here, symbols exist as T but
+ * cannot be imported at link-time.
+ */
+#define LWS_VISIBLE
+#define LWS_EXTERN
+#endif
+
+#endif /* not shared */
+
#define LWS_WARN_DEPRECATED __attribute__ ((deprecated))
#define LWS_FORMAT(string_index) __attribute__ ((format(printf, string_index, string_index+1)))
-#else
+#else /* not GNUC */
+
#define LWS_VISIBLE
#define LWS_WARN_UNUSED_RESULT
#define LWS_WARN_DEPRECATED
#define LWS_FORMAT(string_index)
+#if !defined(LWS_EXTERN)
+#define LWS_EXTERN extern
#endif
+#endif
+
#if defined(__ANDROID__)
#include <netinet/in.h>
#include <unistd.h>
#endif
+#endif
+#ifdef _WIN32
+#define random rand
+#else
+#if !defined(LWS_PLAT_OPTEE)
+#include <sys/time.h>
+#include <unistd.h>
+#endif
#endif
-#if defined(LWS_WITH_LIBEV)
-#include <ev.h>
-#endif /* LWS_WITH_LIBEV */
-#ifdef LWS_WITH_LIBUV
+#if defined(LWS_WITH_LIBUV_INTERNAL)
#include <uv.h>
+
#ifdef LWS_HAVE_UV_VERSION_H
#include <uv-version.h>
#endif
+
#ifdef LWS_HAVE_NEW_UV_VERSION_H
#include <uv/version.h>
#endif
-#endif /* LWS_WITH_LIBUV */
-#if defined(LWS_WITH_LIBEVENT)
-#include <event2/event.h>
-#endif /* LWS_WITH_LIBEVENT */
-
-#ifndef LWS_EXTERN
-#define LWS_EXTERN extern
-#endif
-
-#ifdef _WIN32
-#define random rand
-#else
-#if !defined(LWS_PLAT_OPTEE)
-#include <sys/time.h>
-#include <unistd.h>
-#endif
#endif
#if defined(LWS_WITH_TLS)
#define MBEDTLS_CONFIG_FILE <mbedtls/esp_config.h>
#endif
#endif
+#if defined(LWS_WITH_TLS)
#include <mbedtls/ssl.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
+#endif
#else
#include <openssl/ssl.h>
#if !defined(LWS_WITH_MBEDTLS)
typedef HANDLE lws_filefd_type;
#endif
-struct lws_pollfd {
- lws_sockfd_type fd; /**< file descriptor */
- SHORT events; /**< which events to respond to */
- SHORT revents; /**< which events happened */
-};
-#define LWS_POLLHUP (FD_CLOSE)
-#define LWS_POLLIN (FD_READ | FD_ACCEPT)
-#define LWS_POLLOUT (FD_WRITE)
-#if !defined(pid_t)
-#define pid_t int
-#endif
+#define lws_pollfd pollfd
+#define LWS_POLLHUP (POLLHUP)
+#define LWS_POLLIN (POLLRDNORM | POLLRDBAND)
+#define LWS_POLLOUT (POLLWRNORM)
#else
#if defined(LWS_PLAT_FREERTOS)
#include <libwebsockets/lws-freertos.h>
-#if defined(LWS_WITH_ESP32)
-#include <libwebsockets/lws-esp32.h>
-#endif
#else
typedef int lws_sockfd_type;
typedef int lws_filefd_type;
struct lws;
#include <libwebsockets/lws-dll2.h>
+#include <libwebsockets/lws-fault-injection.h>
#include <libwebsockets/lws-timeout-timer.h>
+#if defined(LWS_WITH_SYS_SMD)
+#include <libwebsockets/lws-smd.h>
+#endif
#include <libwebsockets/lws-state.h>
#include <libwebsockets/lws-retry.h>
#include <libwebsockets/lws-adopt.h>
#include <libwebsockets/lws-network-helper.h>
+#include <libwebsockets/lws-metrics.h>
#include <libwebsockets/lws-system.h>
-#include <libwebsockets/lws-detailed-latency.h>
#include <libwebsockets/lws-ws-close.h>
#include <libwebsockets/lws-callbacks.h>
#include <libwebsockets/lws-ws-state.h>
#include <libwebsockets/lws-ws-ext.h>
#include <libwebsockets/lws-protocols-plugins.h>
-#include <libwebsockets/lws-plugin-generic-sessions.h>
+
#include <libwebsockets/lws-context-vhost.h>
+
+#if defined(LWS_WITH_CONMON)
+#include <libwebsockets/lws-conmon.h>
+#endif
+
#if defined(LWS_ROLE_MQTT)
#include <libwebsockets/lws-mqtt.h>
#endif
#include <libwebsockets/lws-vfs.h>
#endif
#include <libwebsockets/lws-lejp.h>
-#include <libwebsockets/lws-stats.h>
#include <libwebsockets/lws-struct.h>
#include <libwebsockets/lws-threadpool.h>
#include <libwebsockets/lws-tokenize.h>
#if defined(LWS_WITH_TLS)
+#include <libwebsockets/lws-tls-sessions.h>
+
#if defined(LWS_WITH_MBEDTLS)
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#endif
+#include <libwebsockets/lws-eventlib-exports.h>
+#include <libwebsockets/lws-i2c.h>
+#include <libwebsockets/lws-spi.h>
+#include <libwebsockets/lws-gpio.h>
+#include <libwebsockets/lws-bb-i2c.h>
+#include <libwebsockets/lws-bb-spi.h>
+#include <libwebsockets/lws-button.h>
+#include <libwebsockets/lws-led.h>
+#include <libwebsockets/lws-pwm.h>
+#include <libwebsockets/lws-display.h>
+#include <libwebsockets/lws-ssd1306-i2c.h>
+#include <libwebsockets/lws-ili9341-spi.h>
+#include <libwebsockets/lws-settings.h>
+#include <libwebsockets/lws-netdev.h>
+
#ifdef __cplusplus
}
#endif
lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);
typedef enum {
- LWS_ADOPT_RAW_FILE_DESC = 0, /* convenience constant */
- LWS_ADOPT_HTTP = 1, /* flag: absent implies RAW */
- LWS_ADOPT_SOCKET = 2, /* flag: absent implies file descr */
- LWS_ADOPT_ALLOW_SSL = 4, /* flag: if set requires LWS_ADOPT_SOCKET */
- LWS_ADOPT_FLAG_UDP = 16, /* flag: socket is UDP */
- LWS_ADOPT_FLAG_RAW_PROXY = 32, /* flag: raw proxy */
+ LWS_ADOPT_RAW_FILE_DESC = 0, /* convenience constant */
+ LWS_ADOPT_HTTP = 1, /* flag: absent implies RAW */
+ LWS_ADOPT_SOCKET = 2, /* flag: absent implies file */
+ LWS_ADOPT_ALLOW_SSL = 4, /* flag: use tls */
+ LWS_ADOPT_FLAG_UDP = 16, /* flag: socket is UDP */
+ LWS_ADOPT_FLAG_RAW_PROXY = 32, /* flag: raw proxy */
LWS_ADOPT_RAW_SOCKET_UDP = LWS_ADOPT_SOCKET | LWS_ADOPT_FLAG_UDP,
} lws_adoption_type;
lws_filefd_type filefd;
} lws_sock_file_fd_type;
+#if defined(LWS_ESP_PLATFORM)
+#include <lwip/sockets.h>
+#endif
+
+typedef union {
+#if defined(LWS_WITH_IPV6)
+ struct sockaddr_in6 sa6;
+#else
+#if defined(LWS_ESP_PLATFORM)
+ uint8_t _pad_sa6[28];
+#endif
+#endif
+ struct sockaddr_in sa4;
+} lws_sockaddr46;
+
+#define sa46_sockaddr(_sa46) ((struct sockaddr *)(_sa46))
+
+#if defined(LWS_WITH_IPV6)
+#define sa46_socklen(_sa46) (socklen_t)((_sa46)->sa4.sin_family == AF_INET ? \
+ sizeof(struct sockaddr_in) : \
+ sizeof(struct sockaddr_in6))
+#define sa46_sockport(_sa46, _sp) { if ((_sa46)->sa4.sin_family == AF_INET) \
+ (_sa46)->sa4.sin_port = (_sp); else \
+ (_sa46)->sa6.sin6_port = (_sp); }
+#define sa46_address(_sa46) ((uint8_t *)((_sa46)->sa4.sin_family == AF_INET ? \
+ &_sa46->sa4.sin_addr : &_sa46->sa6.sin6_addr ))
+#else
+#define sa46_socklen(_sa46) (socklen_t)sizeof(struct sockaddr_in)
+#define sa46_sockport(_sa46, _sp) (_sa46)->sa4.sin_port = (_sp)
+#define sa46_address(_sa46) (uint8_t *)&_sa46->sa4.sin_addr
+#endif
+
+#define sa46_address_len(_sa46) ((_sa46)->sa4.sin_family == AF_INET ? 4 : 16)
+
#if defined(LWS_WITH_UDP)
struct lws_udp {
- struct sockaddr sa;
- socklen_t salen;
-
- struct sockaddr sa_pending;
- socklen_t salen_pending;
+ lws_sockaddr46 sa46;
+ lws_sockaddr46 sa46_pending;
+ uint8_t connected:1;
};
#endif
const char *vh_prot_name; /**< NULL or vh protocol name to bind raw connection to */
struct lws *parent; /**< NULL or struct lws to attach new_wsi to as a child */
void *opaque; /**< opaque pointer to set on created wsi */
+ const char *fi_wsi_name; /**< NULL, or Fault Injection inheritence filter for wsi=string/ context faults */
} lws_adopt_desc_t;
/**
* \param parent_wsi: NULL or parent wsi new wsi will be a child of
* \param opaque: set created wsi opaque ptr to this
* \param retry_policy: NULL for vhost default policy else wsi specific policy
+ * \param fi_wsi_name: NULL, or string to inherit Fault Injection rules in
+ * form "wsi=string/rule". "wsi/rule" faults will be
+ * automatically applied as well. It's done at creation
+ * time so the rules can, eg, inject faults related to
+ * creation.
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port,
int flags, const char *protocol_name, const char *ifname,
struct lws *parent_wsi, void *opaque,
- const lws_retry_bo_t *retry_policy);
+ const lws_retry_bo_t *retry_policy, const char *fi_wsi_name);
#endif
LADNS_RET_CONTINUING
} lws_async_dns_retcode_t;
+struct addrinfo;
+
typedef struct lws * (*lws_async_dns_cb_t)(struct lws *wsi, const char *ads,
- const struct addrinfo *result, int n,
- void *opaque);
+ const struct addrinfo *result, int n, void *opaque);
/**
* lws_async_dns_query() - perform a dns lookup using async dns
--- /dev/null
+/*
+ * I2C - bitbanged generic gpio implementation
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * This is like an abstract class for gpio, a real implementation provides
+ * functions for the ops that use the underlying OS gpio arrangements.
+ */
+
+typedef struct lws_bb_i2c {
+ lws_i2c_ops_t bb_ops; /* init to lws_bb_i2c_ops */
+
+ /* implementation-specific members */
+
+ _lws_plat_gpio_t scl;
+ _lws_plat_gpio_t sda;
+
+ const lws_gpio_ops_t *gpio;
+ void (*delay)(void);
+} lws_bb_i2c_t;
+
+#define lws_bb_i2c_ops \
+ { \
+ .init = lws_bb_i2c_init, \
+ .start = lws_bb_i2c_start, \
+ .stop = lws_bb_i2c_stop, \
+ .write = lws_bb_i2c_write, \
+ .read = lws_bb_i2c_read, \
+ .set_ack = lws_bb_i2c_set_ack, \
+ }
+
+int
+lws_bb_i2c_init(const lws_i2c_ops_t *octx);
+
+int
+lws_bb_i2c_start(const lws_i2c_ops_t *octx);
+
+void
+lws_bb_i2c_stop(const lws_i2c_ops_t *octx);
+
+int
+lws_bb_i2c_write(const lws_i2c_ops_t *octx, uint8_t data);
+
+int
+lws_bb_i2c_read(const lws_i2c_ops_t *octx);
+
+void
+lws_bb_i2c_set_ack(const lws_i2c_ops_t *octx, int ack);
--- /dev/null
+/*
+ * I2C - bitbanged generic gpio implementation
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * This is like an abstract class for gpio, a real implementation provides
+ * functions for the ops that use the underlying OS gpio arrangements.
+ */
+
+#define LWSBBSPI_FLAG_USE_NCMD3 (1 << 7)
+#define LWSBBSPI_FLAG_USE_NCMD2 (1 << 6)
+#define LWSBBSPI_FLAG_USE_NCMD1 (1 << 5)
+#define LWSBBSPI_FLAG_USE_NCMD0 (1 << 4)
+#define LWSBBSPI_FLAG_USE_NCS3 (1 << 3)
+#define LWSBBSPI_FLAG_USE_NCS2 (1 << 2)
+#define LWSBBSPI_FLAG_USE_NCS1 (1 << 1)
+#define LWSBBSPI_FLAG_USE_NCS0 (1 << 0)
+
+#define LWS_SPI_BB_MAX_CH 4
+
+typedef struct lws_bb_spi {
+ lws_spi_ops_t bb_ops; /* init to lws_bb_spi_ops */
+
+ /* implementation-specific members */
+ const lws_gpio_ops_t *gpio;
+
+ _lws_plat_gpio_t clk;
+ _lws_plat_gpio_t ncs[LWS_SPI_BB_MAX_CH];
+ _lws_plat_gpio_t ncmd[LWS_SPI_BB_MAX_CH];
+ _lws_plat_gpio_t mosi;
+ _lws_plat_gpio_t miso;
+
+ uint8_t flags;
+} lws_bb_spi_t;
+
+#define lws_bb_spi_ops \
+ .init = lws_bb_spi_init, \
+ .queue = lws_bb_spi_queue
+
+int
+lws_bb_spi_init(const lws_spi_ops_t *octx);
+
+int
+lws_bb_spi_queue(const lws_spi_ops_t *octx, const lws_spi_desc_t *desc);
--- /dev/null
+/*
+ * Generic button ops
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * Leverages the lws generic gpio pieces to bind gpio buttons to smd events
+ */
+
+#if !defined(__LWS_BUTTON_H__)
+#define __LWS_BUTTON_H__
+
+typedef uint16_t lws_button_idx_t;
+
+/* actual minimum may be 1 x RTOS tick depending on platform */
+#define LWS_BUTTON_MON_TIMER_MS 5
+
+typedef void (*lws_button_cb_t)(void *opaque, lws_button_idx_t idx, int state);
+
+/* These are specified in ms but the granularity is LWS_BUTTON_MON_TIMER_MS,
+ * which may have been rounded up to an RTOS tick depending on platform */
+
+enum {
+ LWSBTNRGMFLAG_CLASSIFY_DOUBLECLICK = (1 << 0)
+};
+
+typedef struct lws_button_regime {
+ uint16_t ms_min_down;
+ uint16_t ms_min_down_longpress;
+ uint16_t ms_up_settle;
+ uint16_t ms_doubleclick_grace;
+ uint16_t ms_repeat_down;
+ uint8_t flags;
+ /**< when double-click classification is enabled, clicks are delayed
+ * by ms_min_down + ms_doubleclick_grace to wait and see if it will
+ * become a double-click. Set LWSBTNRGMFLAG_CLASSIFY_DOUBLECLICK to
+ * enable it or leave that bit at 0 to get faster single-click
+ * classification.
+ */
+} lws_button_regime_t;
+
+/*
+ * This is the const part of the button controller, describing the static
+ * bindings to gpio, and lws_smd event name information
+ */
+
+typedef struct lws_button_map {
+ _lws_plat_gpio_t gpio;
+ const char *smd_interaction_name;
+ const lws_button_regime_t *regime;
+ /**< a default regime is applied if this is left NULL */
+} lws_button_map_t;
+
+typedef struct lws_button_controller {
+ const char *smd_bc_name;
+ const lws_gpio_ops_t *gpio_ops;
+ const lws_button_map_t *button_map;
+ lws_button_idx_t active_state_bitmap;
+ uint8_t count_buttons;
+} lws_button_controller_t;
+
+struct lws_button_state; /* opaque */
+
+/**
+ * lws_button_controller_create() - instantiate a button controller
+ *
+ * \param ctx: the lws_context
+ * \param controller: the static controller definition
+ *
+ * Instantiates a button controller from a static definition of the buttons
+ * and their smd names, and active levels, and binds it to a gpio implementation
+ */
+
+LWS_VISIBLE LWS_EXTERN struct lws_button_state *
+lws_button_controller_create(struct lws_context *ctx,
+ const lws_button_controller_t *controller);
+
+/**
+ * lws_button_controller_destroy() - destroys a button controller
+ *
+ * \param bcs: button controller state previously created
+ *
+ * Disables all buttons and then destroys and frees a previously created
+ * button controller.
+ */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_button_controller_destroy(struct lws_button_state *bcs);
+
+
+LWS_VISIBLE LWS_EXTERN lws_button_idx_t
+lws_button_get_bit(struct lws_button_state *bcs, const char *name);
+
+/*
+ * lws_button_enable() - enable and disable buttons
+ */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_button_enable(struct lws_button_state *bcs,
+ lws_button_idx_t _reset, lws_button_idx_t _set);
+
+#endif
+
};
/*
+ * With LWS_CALLBACK_FILTER_NETWORK_CONNECTION callback, user_data pointer
+ * points to one of these
+ */
+
+struct lws_filter_network_conn_args {
+ struct sockaddr_storage cli_addr;
+ socklen_t clilen;
+ lws_sockfd_type accept_fd;
+};
+
+/*
* NOTE: These public enums are part of the abi. If you want to add one,
* add it at where specified so existing users are unaffected.
*/
* lws know by calling lws_client_http_body_pending(wsi, 0)
*/
+ LWS_CALLBACK_CLIENT_HTTP_REDIRECT = 104,
+ /**< we're handling a 3xx redirect... return nonzero to hang up */
+
LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL = 85,
LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL = 76,
/**< called when a client connects to
* the server at network level; the connection is accepted but then
* passed to this callback to decide whether to hang up immediately
- * or not, based on the client IP. in contains the connection
- * socket's descriptor. Since the client connection information is
- * not available yet, wsi still pointing to the main server socket.
+ * or not, based on the client IP.
+ *
+ * user_data in the callback points to a
+ * struct lws_filter_network_conn_args that is prepared with the
+ * sockfd, and the peer's address information.
+ *
+ * in contains the connection socket's descriptor.
+ *
+ * Since the client connection information is not available yet,
+ * wsi still pointing to the main server socket.
+ *
* Return non-zero to terminate the connection before sending or
* receiving anything. Because this happens immediately after the
* network connection from the client, there's no websocket protocol
* destroyed. in is the child wsi.
*/
+ LWS_CALLBACK_CONNECTING = 105,
+ /**< Called before a socketfd is about to connect(). In is the
+ * socketfd, cast to a (void *), if on a platform where the socketfd
+ * is an int, recover portably using (lws_sockfd_type)(intptr_t)in.
+ *
+ * It's also called in SOCKS5 or http_proxy cases where the socketfd is
+ * going to try to connect to its proxy.
+ */
+
/* ---------------------------------------------------------------------
* ----- Callbacks related to TLS certificate management -----
*/
* HTTP/2: always possible... uses parallel streams
*/
LCCSCF_MUXABLE_STREAM = (1 << 17),
+ LCCSCF_H2_PRIOR_KNOWLEDGE = (1 << 18),
+ LCCSCF_WAKE_SUSPEND__VALIDITY = (1 << 19),
+ /* our validity checks are important enough to wake from suspend */
+ LCCSCF_PRIORITIZE_READS = (1 << 20),
+ /**<
+ * Normally lws balances reads and writes on all connections, so both
+ * are possible even on busy connections, and we go around the event
+ * loop more often to facilitate that, even if there is pending data.
+ *
+ * This flag indicates that you want to handle any pending reads on this
+ * connection without yielding the service loop for anything else. This
+ * means you may block other connection processing in favour of incoming
+ * data processing on this one if it receives back to back incoming rx.
+ */
+ LCCSCF_SECSTREAM_CLIENT = (1 << 21),
+ /**< used to mark client wsi as bound to secure stream */
+ LCCSCF_SECSTREAM_PROXY_LINK = (1 << 22),
+ /**< client is a link between SS client and SS proxy */
+ LCCSCF_SECSTREAM_PROXY_ONWARD = (1 << 23),
+ /**< client the SS proxy's onward connection */
+
+ LCCSCF_IP_LOW_LATENCY = (1 << 24),
+ /**< set the "low delay" bit on the IP packets of this connection */
+ LCCSCF_IP_HIGH_THROUGHPUT = (1 << 25),
+ /**< set the "high throughput" bit on the IP packets of this
+ * connection */
+ LCCSCF_IP_HIGH_RELIABILITY = (1 << 26),
+ /**< set the "high reliability" bit on the IP packets of this
+ * connection */
+ LCCSCF_IP_LOW_COST = (1 << 27),
+ /**< set the "minimize monetary cost" bit on the IP packets of this
+ * connection */
+ LCCSCF_CONMON = (1 << 28),
+ /**< If LWS_WITH_CONMON enabled for build, keeps a copy of the
+ * getaddrinfo results so they can be queried subsequently */
};
/** struct lws_client_connect_info - parameters to connect with when using
* to the client connection.
*/
+ uint8_t priority;
+ /**< 0 means normal priority... otherwise sets the IP priority on
+ * packets coming from this connection, from 1 - 7. Setting 7
+ * (network management priority) requires CAP_NET_ADMIN capability but
+ * the others can be set by anyone.
+ */
+
#if defined(LWS_ROLE_MQTT)
const lws_mqtt_client_connect_param_t *mqtt_cp;
#else
void *mqtt_cp;
#endif
+#if defined(LWS_WITH_SYS_FAULT_INJECTION)
+ lws_fi_ctx_t fic;
+ /**< Attach external Fault Injection context to the client wsi,
+ * hierarchy is wsi -> vhost -> context */
+#endif
+ /* for convenience, available when FI disabled in build */
+ const char *fi_wsi_name;
+ /**< specific Fault Injection namespace name for wsi created for this
+ * connection, allows targeting by "wsi=XXX/..." if you give XXX here.
+ */
+
+ uint16_t keep_warm_secs;
+ /**< 0 means 5s. If the client connection to the endpoint becomes idle,
+ * defer closing it for this many seconds in case another outgoing
+ * connection to the same endpoint turns up.
+ */
+
/* Add new things just above here ---^
* This is part of the ABI, don't needlessly break compatibility
*
LWS_VISIBLE LWS_EXTERN int
lws_http_basic_auth_gen(const char *user, const char *pw, char *buf, size_t len);
+/**
+ * lws_tls_session_is_reused() - returns nonzero if tls session was cached
+ *
+ * \param wsi: the wsi
+ *
+ * Returns zero if the tls session is fresh, else nonzero if the tls session was
+ * taken from the cache. If lws is built with LWS_WITH_TLS_SESSIONS and the vhost
+ * was created with the option LWS_SERVER_OPTION_ENABLE_TLS_SESSION_CACHE, then
+ * on full tls session establishment of a client connection, the session is added
+ * to the tls cache.
+ *
+ * This lets you find out if your session was new (0) or from the cache (nonzero),
+ * it'a mainly useful for stats and testing.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_tls_session_is_reused(struct lws *wsi);
+
///@}
--- /dev/null
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ */
+
+/** \defgroup conmon Connection Latency information
+ * ## Connection Latency information
+ *
+ * When LWS_WITH_CONMON is enabled at build, collects detailed statistics
+ * about the client connection setup latency, available to the connection
+ * itself
+ */
+///@{
+
+/* enough for 4191us, or just over an hour */
+typedef uint32_t lws_conmon_interval_us_t;
+
+/*
+ * Connection latency information... note that not all wsi actually make
+ * connections, for example h2 streams after the initial one will have 0
+ * for everything except ciu_txn_resp.
+ *
+ * If represented in JSON, it should look like this
+ *
+ * {
+ * "peer": "46.105.127.147",
+ * "dns_us": 1234,
+ * "sockconn_us": 1234,
+ * "tls_us": 1234,
+ * "txn_resp_us": 1234,
+ * "dns":["46.105.127.147", "2001:41d0:2:ee93::1"]
+ * }
+ */
+
+struct lws_conmon {
+ lws_sockaddr46 peer46;
+ /**< The peer we actually connected to, if any. .peer46.sa4.sa_family
+ * is either 0 if invalid, or the AF_ */
+
+ struct addrinfo *dns_results_copy;
+ /**< NULL, or Allocated copy of dns results, owned by this object and
+ * freed when object destroyed.
+ * Only set if client flag LCCSCF_CONMON applied */
+
+ lws_conmon_interval_us_t ciu_dns;
+ /**< 0, or if a socket connection, us taken to acquire this DNS response
+ *
+ */
+ lws_conmon_interval_us_t ciu_sockconn;
+ /**< 0, or if connection-based, the us interval between the socket
+ * connect() attempt that succeeded, and the connection setup */
+ lws_conmon_interval_us_t ciu_tls;
+ /**< 0 if no tls, or us taken to establish the tls tunnel */
+ lws_conmon_interval_us_t ciu_txn_resp;
+ /**< 0, or if the protocol supports transactions, the interval between
+ * sending the transaction request and starting to receive the resp */
+};
+
+/**
+ * lws_conmon_wsi_take() - create a connection latency object from client wsi
+ *
+ * \param context: lws wsi
+ * \param dest: conmon struct to fill
+ *
+ * Copies wsi conmon data into the caller's struct. Passes ownership of
+ * any allocations in the addrinfo list to the caller, lws will not delete that
+ * any more on wsi close after this call. The caller must call
+ * lws_conmon_release() on the struct to destroy any addrinfo in the struct
+ * that is prepared by this eventually but it can defer it as long as it wants.
+ *
+ * Other than the addrinfo list, the contents of the returned object are
+ * completely selfcontained and don't point outside of the object itself, ie,
+ * everything else in there remains in scope while the object itself does.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_conmon_wsi_take(struct lws *wsi, struct lws_conmon *dest);
+
+/**
+ * lws_conmon_release() - free any allocations in the conmon struct
+ *
+ * \param conmon: pointer to conmon struct
+ *
+ * Destroys any allocations in the conmon struct so it can go out of scope.
+ * It doesn't free \p dest itself, it's designed to clean out a struct that
+ * is on the stack or embedded in another object.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_conmon_release(struct lws_conmon *conmon);
+
+///@}
/*
* libwebsockets - small server side websockets and web server implementation
*
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
#define LWS_SERVER_OPTION_GLIB (1ll << 33)
/**< (CTX) Use glib event loop */
+#define LWS_SERVER_OPTION_H2_PRIOR_KNOWLEDGE (1ll << 34)
+ /**< (VH) Tell the vhost to treat plain text http connections as
+ * H2 with prior knowledge (no upgrade request involved)
+ */
+
+#define LWS_SERVER_OPTION_NO_LWS_SYSTEM_STATES (1ll << 35)
+ /**< (CTX) Disable lws_system state, eg, because we are a secure streams
+ * proxy client that is not trying to track system state by itself. */
+
+#define LWS_SERVER_OPTION_SS_PROXY (1ll << 36)
+ /**< (VH) We are being a SS Proxy listen socket for the vhost */
+
+#define LWS_SERVER_OPTION_SDEVENT (1ll << 37)
+ /**< (CTX) Use sd-event loop */
+
+#define LWS_SERVER_OPTION_ULOOP (1ll << 38)
+ /**< (CTX) Use libubox / uloop event loop */
+
+#define LWS_SERVER_OPTION_DISABLE_TLS_SESSION_CACHE (1ll << 39)
+ /**< (VHOST) Disallow use of client tls caching (on by default) */
+
+
/****** add new things just above ---^ ******/
struct lws_plat_file_ops;
struct lws_ss_policy;
struct lws_ss_plugin;
+struct lws_metric_policy;
typedef int (*lws_context_ready_cb_t)(struct lws_context *context);
+typedef int (*lws_peer_limits_notify_t)(struct lws_context *ctx,
+ lws_sockfd_type sockfd,
+ lws_sockaddr46 *sa46);
+
/** struct lws_context_creation_info - parameters to create context and /or vhost with
*
* This is also used to create vhosts.... if LWS_SERVER_OPTION_EXPLICIT_VHOSTS
* at the same time as the context, they are expected to be created afterwards.
*/
struct lws_context_creation_info {
- int port;
- /**< VHOST: Port to listen on. Use CONTEXT_PORT_NO_LISTEN to suppress
- * listening for a client. Use CONTEXT_PORT_NO_LISTEN_SERVER if you are
- * writing a server but you are using \ref sock-adopt instead of the
- * built-in listener.
- *
- * You can also set port to 0, in which case the kernel will pick
- * a random port that is not already in use. You can find out what
- * port the vhost is listening on using lws_get_vhost_listen_port() */
+#if defined(LWS_WITH_NETWORK)
const char *iface;
/**< VHOST: NULL to bind the listen socket to all interfaces, or the
* interface name, eg, "eth2"
* entry that has a NULL callback pointer. SEE ALSO .pprotocols below,
* which gives an alternative way to provide an array of pointers to
* protocol structs. */
+#if defined(LWS_ROLE_WS)
const struct lws_extension *extensions;
/**< VHOST: NULL or array of lws_extension structs listing the
* extensions this context supports. */
+#endif
+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
const struct lws_token_limits *token_limits;
/**< CONTEXT: NULL or struct lws_token_limits pointer which is
* initialized with a token length limit for each possible WSI_TOKEN_ */
+ const char *http_proxy_address;
+ /**< VHOST: If non-NULL, attempts to proxy via the given address.
+ * If proxy auth is required, use format
+ * "username:password\@server:port" */
+ const struct lws_protocol_vhost_options *headers;
+ /**< VHOST: pointer to optional linked list of per-vhost
+ * canned headers that are added to server responses */
+
+ const struct lws_protocol_vhost_options *reject_service_keywords;
+ /**< CONTEXT: Optional list of keywords and rejection codes + text.
+ *
+ * The keywords are checked for existing in the user agent string.
+ *
+ * Eg, "badrobot" "404 Not Found"
+ */
+ const struct lws_protocol_vhost_options *pvo;
+ /**< VHOST: pointer to optional linked list of per-vhost
+ * options made accessible to protocols */
+ const char *log_filepath;
+ /**< VHOST: filepath to append logs to... this is opened before
+ * any dropping of initial privileges */
+ const struct lws_http_mount *mounts;
+ /**< VHOST: optional linked list of mounts for this vhost */
+ const char *server_string;
+ /**< CONTEXT: string used in HTTP headers to identify server
+ * software, if NULL, "libwebsockets". */
+
+ const char *error_document_404;
+ /**< VHOST: If non-NULL, when asked to serve a non-existent file,
+ * lws attempts to server this url path instead. Eg,
+ * "/404.html" */
+ int port;
+ /**< VHOST: Port to listen on. Use CONTEXT_PORT_NO_LISTEN to suppress
+ * listening for a client. Use CONTEXT_PORT_NO_LISTEN_SERVER if you are
+ * writing a server but you are using \ref sock-adopt instead of the
+ * built-in listener.
+ *
+ * You can also set port to 0, in which case the kernel will pick
+ * a random port that is not already in use. You can find out what
+ * port the vhost is listening on using lws_get_vhost_listen_port() */
+
+ unsigned int http_proxy_port;
+ /**< VHOST: If http_proxy_address was non-NULL, uses this port */
+ unsigned int max_http_header_data2;
+ /**< CONTEXT: if max_http_header_data is 0 and this
+ * is nonzero, this will be used in place of the default. It's
+ * like this for compatibility with the original short version,
+ * this is unsigned int length. */
+ unsigned int max_http_header_pool2;
+ /**< CONTEXT: if max_http_header_pool is 0 and this
+ * is nonzero, this will be used in place of the default. It's
+ * like this for compatibility with the original short version:
+ * this is unsigned int length. */
+
+ int keepalive_timeout;
+ /**< VHOST: (default = 0 = 5s, 31s for http/2) seconds to allow remote
+ * client to hold on to an idle HTTP/1.1 connection. Timeout lifetime
+ * applied to idle h2 network connections */
+ uint32_t http2_settings[7];
+ /**< VHOST: if http2_settings[0] is nonzero, the values given in
+ * http2_settings[1]..[6] are used instead of the lws
+ * platform default values.
+ * Just leave all at 0 if you don't care.
+ */
+
+ unsigned short max_http_header_data;
+ /**< CONTEXT: The max amount of header payload that can be handled
+ * in an http request (unrecognized header payload is dropped) */
+ unsigned short max_http_header_pool;
+ /**< CONTEXT: The max number of connections with http headers that
+ * can be processed simultaneously (the corresponding memory is
+ * allocated and deallocated dynamically as needed). If the pool is
+ * fully busy new incoming connections must wait for accept until one
+ * becomes free. 0 = allow as many ah as number of availble fds for
+ * the process */
+
+#endif
+
+#if defined(LWS_WITH_TLS)
const char *ssl_private_key_password;
/**< VHOST: NULL or the passphrase needed for the private key. (For
* backwards compatibility, this can also be used to pass the client
* SEE .tls1_3_plus_cipher_list and .client_tls_1_3_plus_cipher_list
* for the equivalent for tls1.3.
*/
- const char *http_proxy_address;
- /**< VHOST: If non-NULL, attempts to proxy via the given address.
- * If proxy auth is required, use format
- * "username:password\@server:port" */
- unsigned int http_proxy_port;
- /**< VHOST: If http_proxy_address was non-NULL, uses this port */
- int gid;
+ const char *ecdh_curve;
+ /**< VHOST: if NULL, defaults to initializing server with
+ * "prime256v1" */
+ const char *tls1_3_plus_cipher_list;
+ /**< VHOST: List of valid ciphers to use for incoming server connections
+ * ON TLS1.3 AND ABOVE (eg, "TLS_CHACHA20_POLY1305_SHA256" on this vhost
+ * or you can leave it as NULL to get "DEFAULT".
+ * SEE .client_tls_1_3_plus_cipher_list to do the same on the vhost
+ * client SSL_CTX.
+ */
+
+ const void *server_ssl_cert_mem;
+ /**< VHOST: Alternative for \p ssl_cert_filepath that allows setting
+ * from memory instead of from a file. At most one of
+ * \p ssl_cert_filepath or \p server_ssl_cert_mem should be non-NULL. */
+ const void *server_ssl_private_key_mem;
+ /**< VHOST: Alternative for \p ssl_private_key_filepath allowing
+ * init from a private key in memory instead of a file. At most one
+ * of \p ssl_private_key_filepath or \p server_ssl_private_key_mem
+ * should be non-NULL. */
+ const void *server_ssl_ca_mem;
+ /**< VHOST: Alternative for \p ssl_ca_filepath allowing
+ * init from a CA cert in memory instead of a file. At most one
+ * of \p ssl_ca_filepath or \p server_ssl_ca_mem should be non-NULL. */
+
+ long ssl_options_set;
+ /**< VHOST: Any bits set here will be set as server SSL options */
+ long ssl_options_clear;
+ /**< VHOST: Any bits set here will be cleared as server SSL options */
+ int simultaneous_ssl_restriction;
+ /**< CONTEXT: 0 (no limit) or limit of simultaneous SSL sessions
+ * possible.*/
+ int ssl_info_event_mask;
+ /**< VHOST: mask of ssl events to be reported on LWS_CALLBACK_SSL_INFO
+ * callback for connections on this vhost. The mask values are of
+ * the form SSL_CB_ALERT, defined in openssl/ssl.h. The default of
+ * 0 means no info events will be reported.
+ */
+ unsigned int server_ssl_cert_mem_len;
+ /**< VHOST: Server SSL context init: length of server_ssl_cert_mem in
+ * bytes */
+ unsigned int server_ssl_private_key_mem_len;
+ /**< VHOST: length of \p server_ssl_private_key_mem in memory */
+ unsigned int server_ssl_ca_mem_len;
+ /**< VHOST: length of \p server_ssl_ca_mem in memory */
+
+ const char *alpn;
+ /**< CONTEXT: If non-NULL, default list of advertised alpn, comma-
+ * separated
+ *
+ * VHOST: If non-NULL, per-vhost list of advertised alpn, comma-
+ * separated
+ */
+
+
+#if defined(LWS_WITH_CLIENT)
+ const char *client_ssl_private_key_password;
+ /**< VHOST: Client SSL context init: NULL or the passphrase needed
+ * for the private key */
+ const char *client_ssl_cert_filepath;
+ /**< VHOST: Client SSL context init: The certificate the client
+ * should present to the peer on connection */
+ const void *client_ssl_cert_mem;
+ /**< VHOST: Client SSL context init: client certificate memory buffer or
+ * NULL... use this to load client cert from memory instead of file */
+ unsigned int client_ssl_cert_mem_len;
+ /**< VHOST: Client SSL context init: length of client_ssl_cert_mem in
+ * bytes */
+ const char *client_ssl_private_key_filepath;
+ /**< VHOST: Client SSL context init: filepath to client private key
+ * if this is set to NULL but client_ssl_cert_filepath is set, you
+ * can handle the LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS
+ * callback of protocols[0] to allow setting of the private key directly
+ * via tls library calls */
+ const void *client_ssl_key_mem;
+ /**< VHOST: Client SSL context init: client key memory buffer or
+ * NULL... use this to load client key from memory instead of file */
+ const char *client_ssl_ca_filepath;
+ /**< VHOST: Client SSL context init: CA certificate filepath or NULL */
+ const void *client_ssl_ca_mem;
+ /**< VHOST: Client SSL context init: CA certificate memory buffer or
+ * NULL... use this to load CA cert from memory instead of file */
+
+ const char *client_ssl_cipher_list;
+ /**< VHOST: Client SSL context init: List of valid ciphers to use (eg,
+ * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
+ * or you can leave it as NULL to get "DEFAULT" */
+ const char *client_tls_1_3_plus_cipher_list;
+ /**< VHOST: List of valid ciphers to use for outgoing client connections
+ * ON TLS1.3 AND ABOVE on this vhost (eg,
+ * "TLS_CHACHA20_POLY1305_SHA256") or you can leave it as NULL to get
+ * "DEFAULT".
+ */
+
+ long ssl_client_options_set;
+ /**< VHOST: Any bits set here will be set as CLIENT SSL options */
+ long ssl_client_options_clear;
+ /**< VHOST: Any bits set here will be cleared as CLIENT SSL options */
+
+
+ unsigned int client_ssl_ca_mem_len;
+ /**< VHOST: Client SSL context init: length of client_ssl_ca_mem in
+ * bytes */
+ unsigned int client_ssl_key_mem_len;
+ /**< VHOST: Client SSL context init: length of client_ssl_key_mem in
+ * bytes */
+
+#endif
+
+#if !defined(LWS_WITH_MBEDTLS)
+ SSL_CTX *provided_client_ssl_ctx;
+ /**< CONTEXT: If non-null, swap out libwebsockets ssl
+ * implementation for the one provided by provided_ssl_ctx.
+ * Libwebsockets no longer is responsible for freeing the context
+ * if this option is selected. */
+#endif
+#endif
+
+ int ka_time;
+ /**< CONTEXT: 0 for no TCP keepalive, otherwise apply this keepalive
+ * timeout to all libwebsocket sockets, client or server */
+ int ka_probes;
+ /**< CONTEXT: if ka_time was nonzero, after the timeout expires how many
+ * times to try to get a response from the peer before giving up
+ * and killing the connection */
+ int ka_interval;
+ /**< CONTEXT: if ka_time was nonzero, how long to wait before each ka_probes
+ * attempt */
+ unsigned int timeout_secs;
+ /**< VHOST: various processes involving network roundtrips in the
+ * library are protected from hanging forever by timeouts. If
+ * nonzero, this member lets you set the timeout used in seconds.
+ * Otherwise a default timeout is used. */
+ unsigned int connect_timeout_secs;
+ /**< VHOST: client connections have this long to find a working server
+ * from the DNS results, or the whole connection times out. If zero,
+ * a default timeout is used */
+ int bind_iface;
+ /**< VHOST: nonzero to strictly bind sockets to the interface name in
+ * .iface (eg, "eth2"), using SO_BIND_TO_DEVICE.
+ *
+ * Requires SO_BINDTODEVICE support from your OS and CAP_NET_RAW
+ * capability.
+ *
+ * Notice that common things like access network interface IP from
+ * your local machine use your lo / loopback interface and will be
+ * disallowed by this.
+ */
+ unsigned int timeout_secs_ah_idle;
+ /**< VHOST: seconds to allow a client to hold an ah without using it.
+ * 0 defaults to 10s. */
+#endif /* WITH_NETWORK */
+
+#if defined(LWS_WITH_TLS_SESSIONS)
+ uint32_t tls_session_timeout;
+ /**< VHOST: seconds until timeout/ttl for newly created sessions.
+ * 0 means default timeout (defined per protocol, usually 300s). */
+ uint32_t tls_session_cache_max;
+ /**< VHOST: 0 for default limit of 10, or the maximum number of
+ * client tls sessions we are willing to cache */
+#endif
+
+ gid_t gid;
/**< CONTEXT: group id to change to after setting listen socket,
* or -1. See also .username below. */
- int uid;
+ uid_t uid;
/**< CONTEXT: user id to change to after setting listen socket,
* or -1. See also .groupname below. */
uint64_t options;
* if you care about giving the context and vhost different user pointer
* values.
*/
- int ka_time;
- /**< CONTEXT: 0 for no TCP keepalive, otherwise apply this keepalive
- * timeout to all libwebsocket sockets, client or server */
- int ka_probes;
- /**< CONTEXT: if ka_time was nonzero, after the timeout expires how many
- * times to try to get a response from the peer before giving up
- * and killing the connection */
- int ka_interval;
- /**< CONTEXT: if ka_time was nonzero, how long to wait before each ka_probes
- * attempt */
-#if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS)
- SSL_CTX *provided_client_ssl_ctx;
- /**< CONTEXT: If non-null, swap out libwebsockets ssl
- * implementation for the one provided by provided_ssl_ctx.
- * Libwebsockets no longer is responsible for freeing the context
- * if this option is selected. */
-#else /* maintain structure layout either way */
- void *provided_client_ssl_ctx; /**< dummy if ssl disabled */
-#endif
-
- unsigned short max_http_header_data;
- /**< CONTEXT: The max amount of header payload that can be handled
- * in an http request (unrecognized header payload is dropped) */
- unsigned short max_http_header_pool;
- /**< CONTEXT: The max number of connections with http headers that
- * can be processed simultaneously (the corresponding memory is
- * allocated and deallocated dynamically as needed). If the pool is
- * fully busy new incoming connections must wait for accept until one
- * becomes free. 0 = allow as many ah as number of availble fds for
- * the process */
-
unsigned int count_threads;
/**< CONTEXT: how many contexts to create in an array, 0 = 1 */
unsigned int fd_limit_per_thread;
* cancel pipe, so you may need to allow for some extras for normal
* operation.
*/
- unsigned int timeout_secs;
- /**< VHOST: various processes involving network roundtrips in the
- * library are protected from hanging forever by timeouts. If
- * nonzero, this member lets you set the timeout used in seconds.
- * Otherwise a default timeout is used. */
- const char *ecdh_curve;
- /**< VHOST: if NULL, defaults to initializing server with
- * "prime256v1" */
const char *vhost_name;
/**< VHOST: name of vhost, must match external DNS name used to
* access the site, like "warmcat.com" as it's used to match
* Host: header and / or SNI name for SSL. */
+#if defined(LWS_WITH_PLUGINS)
const char * const *plugin_dirs;
/**< CONTEXT: NULL, or NULL-terminated array of directories to
* scan for lws protocol plugins at context creation time */
- const struct lws_protocol_vhost_options *pvo;
- /**< VHOST: pointer to optional linked list of per-vhost
- * options made accessible to protocols */
- int keepalive_timeout;
- /**< VHOST: (default = 0 = 5s, 31s for http/2) seconds to allow remote
- * client to hold on to an idle HTTP/1.1 connection. Timeout lifetime
- * applied to idle h2 network connections */
- const char *log_filepath;
- /**< VHOST: filepath to append logs to... this is opened before
- * any dropping of initial privileges */
- const struct lws_http_mount *mounts;
- /**< VHOST: optional linked list of mounts for this vhost */
- const char *server_string;
- /**< CONTEXT: string used in HTTP headers to identify server
- * software, if NULL, "libwebsockets". */
- unsigned int pt_serv_buf_size;
- /**< CONTEXT: 0 = default of 4096. This buffer is used by
- * various service related features including file serving, it
- * defines the max chunk of file that can be sent at once.
- * At the risk of lws having to buffer failed large sends, it
- * can be increased to, eg, 128KiB to improve throughput. */
- unsigned int max_http_header_data2;
- /**< CONTEXT: if max_http_header_data is 0 and this
- * is nonzero, this will be used in place of the default. It's
- * like this for compatibility with the original short version,
- * this is unsigned int length. */
- long ssl_options_set;
- /**< VHOST: Any bits set here will be set as server SSL options */
- long ssl_options_clear;
- /**< VHOST: Any bits set here will be cleared as server SSL options */
- unsigned short ws_ping_pong_interval;
- /**< CONTEXT: 0 for none, else interval in seconds between sending
- * PINGs on idle websocket connections. When the PING is sent,
- * the PONG must come within the normal timeout_secs timeout period
- * or the connection will be dropped.
- * Any RX or TX traffic on the connection restarts the interval timer,
- * so a connection which always sends or receives something at intervals
- * less than the interval given here will never send PINGs / expect
- * PONGs. Conversely as soon as the ws connection is established, an
- * idle connection will do the PING / PONG roundtrip as soon as
- * ws_ping_pong_interval seconds has passed without traffic
- */
- const struct lws_protocol_vhost_options *headers;
- /**< VHOST: pointer to optional linked list of per-vhost
- * canned headers that are added to server responses */
-
- const struct lws_protocol_vhost_options *reject_service_keywords;
- /**< CONTEXT: Optional list of keywords and rejection codes + text.
- *
- * The keywords are checked for existing in the user agent string.
- *
- * Eg, "badrobot" "404 Not Found"
- */
+#endif
void *external_baggage_free_on_destroy;
/**< CONTEXT: NULL, or pointer to something externally malloc'd, that
* should be freed when the context is destroyed. This allows you to
* succeeded to create.
*/
- const char *client_ssl_private_key_password;
- /**< VHOST: Client SSL context init: NULL or the passphrase needed
- * for the private key */
- const char *client_ssl_cert_filepath;
- /**< VHOST: Client SSL context init: The certificate the client
- * should present to the peer on connection */
- const void *client_ssl_cert_mem;
- /**< VHOST: Client SSL context init: client certificate memory buffer or
- * NULL... use this to load client cert from memory instead of file */
- unsigned int client_ssl_cert_mem_len;
- /**< VHOST: Client SSL context init: length of client_ssl_cert_mem in
- * bytes */
- const char *client_ssl_private_key_filepath;
- /**< VHOST: Client SSL context init: filepath to client private key
- * if this is set to NULL but client_ssl_cert_filepath is set, you
- * can handle the LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS
- * callback of protocols[0] to allow setting of the private key directly
- * via tls library calls */
- const char *client_ssl_ca_filepath;
- /**< VHOST: Client SSL context init: CA certificate filepath or NULL */
- const void *client_ssl_ca_mem;
- /**< VHOST: Client SSL context init: CA certificate memory buffer or
- * NULL... use this to load CA cert from memory instead of file */
- unsigned int client_ssl_ca_mem_len;
- /**< VHOST: Client SSL context init: length of client_ssl_ca_mem in
- * bytes */
-
- const char *client_ssl_cipher_list;
- /**< VHOST: Client SSL context init: List of valid ciphers to use (eg,
- * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
- * or you can leave it as NULL to get "DEFAULT" */
+ unsigned int pt_serv_buf_size;
+ /**< CONTEXT: 0 = default of 4096. This buffer is used by
+ * various service related features including file serving, it
+ * defines the max chunk of file that can be sent at once.
+ * At the risk of lws having to buffer failed large sends, it
+ * can be increased to, eg, 128KiB to improve throughput. */
+#if defined(LWS_WITH_FILE_OPS)
const struct lws_plat_file_ops *fops;
/**< CONTEXT: NULL, or pointer to an array of fops structs, terminated
* by a sentinel with NULL .open.
* If NULL, lws provides just the platform file operations struct for
* backwards compatibility.
*/
- int simultaneous_ssl_restriction;
- /**< CONTEXT: 0 (no limit) or limit of simultaneous SSL sessions
- * possible.*/
+#endif
+
+#if defined(LWS_WITH_SOCKS5)
const char *socks_proxy_address;
/**< VHOST: If non-NULL, attempts to proxy via the given address.
* If proxy auth is required, use format
/**< VHOST: If socks_proxy_address was non-NULL, uses this port
* if nonzero, otherwise requires "server:port" in .socks_proxy_address
*/
+#endif
+
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
cap_value_t caps[4];
/**< CONTEXT: array holding Linux capabilities you want to
/**< CONTEXT: count of Linux capabilities in .caps[]. 0 means
* no capabilities will be inherited from root (the default) */
#endif
- int bind_iface;
- /**< VHOST: nonzero to strictly bind sockets to the interface name in
- * .iface (eg, "eth2"), using SO_BIND_TO_DEVICE.
- *
- * Requires SO_BINDTODEVICE support from your OS and CAP_NET_RAW
- * capability.
- *
- * Notice that common things like access network interface IP from
- * your local machine use your lo / loopback interface and will be
- * disallowed by this.
- */
- int ssl_info_event_mask;
- /**< VHOST: mask of ssl events to be reported on LWS_CALLBACK_SSL_INFO
- * callback for connections on this vhost. The mask values are of
- * the form SSL_CB_ALERT, defined in openssl/ssl.h. The default of
- * 0 means no info events will be reported.
- */
- unsigned int timeout_secs_ah_idle;
- /**< VHOST: seconds to allow a client to hold an ah without using it.
- * 0 defaults to 10s. */
- unsigned short ip_limit_ah;
- /**< CONTEXT: max number of ah a single IP may use simultaneously
- * 0 is no limit. This is a soft limit: if the limit is
- * reached, connections from that IP will wait in the ah
- * waiting list and not be able to acquire an ah until
- * a connection belonging to the IP relinquishes one it
- * already has.
- */
- unsigned short ip_limit_wsi;
- /**< CONTEXT: max number of wsi a single IP may use simultaneously.
- * 0 is no limit. This is a hard limit, connections from
- * the same IP will simply be dropped once it acquires the
- * amount of simultaneous wsi / accepted connections
- * given here.
- */
- uint32_t http2_settings[7];
- /**< VHOST: if http2_settings[0] is nonzero, the values given in
- * http2_settings[1]..[6] are used instead of the lws
- * platform default values.
- * Just leave all at 0 if you don't care.
- */
- const char *error_document_404;
- /**< VHOST: If non-NULL, when asked to serve a non-existent file,
- * lws attempts to server this url path instead. Eg,
- * "/404.html" */
- const char *alpn;
- /**< CONTEXT: If non-NULL, default list of advertised alpn, comma-
- * separated
- *
- * VHOST: If non-NULL, per-vhost list of advertised alpn, comma-
- * separated
- */
void **foreign_loops;
/**< CONTEXT: This is ignored if the context is not being started with
* an event loop, ie, .options has a flag like
/**< VHOST: opaque pointer lws ignores but passes to the finalize
* callback. If you don't care, leave it NULL.
*/
- unsigned int max_http_header_pool2;
- /**< CONTEXT: if max_http_header_pool is 0 and this
- * is nonzero, this will be used in place of the default. It's
- * like this for compatibility with the original short version:
- * this is unsigned int length. */
-
- long ssl_client_options_set;
- /**< VHOST: Any bits set here will be set as CLIENT SSL options */
- long ssl_client_options_clear;
- /**< VHOST: Any bits set here will be cleared as CLIENT SSL options */
-
- const char *tls1_3_plus_cipher_list;
- /**< VHOST: List of valid ciphers to use for incoming server connections
- * ON TLS1.3 AND ABOVE (eg, "TLS_CHACHA20_POLY1305_SHA256" on this vhost
- * or you can leave it as NULL to get "DEFAULT".
- * SEE .client_tls_1_3_plus_cipher_list to do the same on the vhost
- * client SSL_CTX.
- */
- const char *client_tls_1_3_plus_cipher_list;
- /**< VHOST: List of valid ciphers to use for outgoing client connections
- * ON TLS1.3 AND ABOVE on this vhost (eg,
- * "TLS_CHACHA20_POLY1305_SHA256") or you can leave it as NULL to get
- * "DEFAULT".
- */
const char *listen_accept_role;
/**< VHOST: NULL for default, or force accepted incoming connections to
* bind to this role. Uses the role names from their ops struct, eg,
* the type of the user data to be known so its size can be given.
*/
- const void *server_ssl_cert_mem;
- /**< VHOST: Alternative for \p ssl_cert_filepath that allows setting
- * from memory instead of from a file. At most one of
- * \p ssl_cert_filepath or \p server_ssl_cert_mem should be non-NULL. */
- unsigned int server_ssl_cert_mem_len;
- /**< VHOST: Server SSL context init: length of server_ssl_cert_mem in
- * bytes */
- const void *server_ssl_private_key_mem;
- /**< VHOST: Alternative for \p ssl_private_key_filepath allowing
- * init from a private key in memory instead of a file. At most one
- * of \p ssl_private_key_filepath or \p server_ssl_private_key_mem
- * should be non-NULL. */
- unsigned int server_ssl_private_key_mem_len;
- /**< VHOST: length of \p server_ssl_private_key_mem in memory */
- const void *server_ssl_ca_mem;
- /**< VHOST: Alternative for \p ssl_ca_filepath allowing
- * init from a CA cert in memory instead of a file. At most one
- * of \p ssl_ca_filepath or \p server_ssl_ca_mem should be non-NULL. */
- unsigned int server_ssl_ca_mem_len;
- /**< VHOST: length of \p server_ssl_ca_mem in memory */
const char *username; /**< CONTEXT: string username for post-init
* permissions. Like .uid but takes a string username. */
const char *groupname; /**< CONTEXT: string groupname for post-init
const lws_system_ops_t *system_ops;
/**< CONTEXT: hook up lws_system_ apis to system-specific
* implementations */
- det_lat_buf_cb_t detailed_latency_cb;
- /**< CONTEXT: NULL, or callback to receive detailed latency information
- * collected for each read and write */
- const char *detailed_latency_filepath;
- /**< CONTEXT: NULL, or filepath to put latency data into */
const lws_retry_bo_t *retry_and_idle_policy;
/**< VHOST: optional retry and idle policy to apply to this vhost.
* Currently only the idle parts are applied to the connections.
*/
+#if defined(LWS_WITH_SYS_STATE)
lws_state_notify_link_t * const *register_notifier_list;
/**< CONTEXT: NULL, or pointer to an array of notifiers that should
* be registered during context creation, so they can see state change
* events from very early on. The array should end with a NULL. */
- uint8_t udp_loss_sim_tx_pc;
- /**< CONTEXT: percentage of udp writes we could have performed
- * to instead not do, in order to simulate and test udp retry flow */
- uint8_t udp_loss_sim_rx_pc;
- /**< CONTEXT: percentage of udp reads we actually received
- * to make disappear, in order to simulate and test udp retry flow */
+#endif
#if defined(LWS_WITH_SECURE_STREAMS)
+#if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
+ const struct lws_ss_policy *pss_policies; /**< CONTEXT: point to first
+ * in a linked-list of streamtype policies prepared by user code */
+#else
const char *pss_policies_json; /**< CONTEXT: point to a string
* containing a JSON description of the secure streams policies. Set
- * to NULL if not using Secure Streams. */
+ * to NULL if not using Secure Streams.
+ * If the platform supports files and the string does not begin with
+ * '{', lws treats the string as a filepath to open to get the JSON
+ * policy.
+ */
+#endif
const struct lws_ss_plugin **pss_plugins; /**< CONTEXT: point to an array
* of pointers to plugin structs here, terminated with a NULL ptr.
* Set to NULL if not using Secure Streams. */
* ss_proxy_bind and the given port */
#endif
+ int rlimit_nofile;
+ /**< 0 = inherit the initial ulimit for files / sockets from the startup
+ * environment. Nonzero = try to set the limit for this process.
+ */
+#if defined(LWS_WITH_PEER_LIMITS)
+ lws_peer_limits_notify_t pl_notify_cb;
+ /**< CONTEXT: NULL, or a callback to receive notifications each time a
+ * connection is being dropped because of peer limits.
+ *
+ * The callback provides the context, and an lws_sockaddr46 with the
+ * peer address and port.
+ */
+ unsigned short ip_limit_ah;
+ /**< CONTEXT: max number of ah a single IP may use simultaneously
+ * 0 is no limit. This is a soft limit: if the limit is
+ * reached, connections from that IP will wait in the ah
+ * waiting list and not be able to acquire an ah until
+ * a connection belonging to the IP relinquishes one it
+ * already has.
+ */
+ unsigned short ip_limit_wsi;
+ /**< CONTEXT: max number of wsi a single IP may use simultaneously.
+ * 0 is no limit. This is a hard limit, connections from
+ * the same IP will simply be dropped once it acquires the
+ * amount of simultaneous wsi / accepted connections
+ * given here.
+ */
+
+#endif /* PEER_LIMITS */
+
+#if defined(LWS_WITH_SYS_FAULT_INJECTION)
+ lws_fi_ctx_t fic;
+ /**< CONTEXT | VHOST: attach external Fault Injection context to the
+ * lws_context or vhost. If creating the context + default vhost in
+ * one step, only the context binds to \p fi. When creating a vhost
+ * otherwise this can bind to the vhost so the faults can be injected
+ * from the start.
+ */
+#endif
+
+#if defined(LWS_WITH_SYS_SMD)
+ lws_smd_notification_cb_t early_smd_cb;
+ /**< CONTEXT: NULL, or an smd notification callback that will be registered
+ * immediately after the smd in the context is initialized. This ensures
+ * you can get all notifications without having to intercept the event loop
+ * creation, eg, when using an event library. Other callbacks can be
+ * registered later manually without problems.
+ */
+ void *early_smd_opaque;
+ lws_smd_class_t early_smd_class_filter;
+ lws_usec_t smd_ttl_us;
+ /**< CONTEXT: SMD messages older than this many us are removed from the
+ * queue and destroyed even if not fully delivered yet. If zero,
+ * defaults to 2 seconds (5 second for FREERTOS).
+ */
+ uint16_t smd_queue_depth;
+ /**< CONTEXT: Maximum queue depth, If zero defaults to 40
+ * (20 for FREERTOS) */
+#endif
+
+#if defined(LWS_WITH_SYS_METRICS)
+ const struct lws_metric_policy *metrics_policies;
+ /**< non-SS policy metrics policies */
+ const char *metrics_prefix;
+ /**< prefix for this context's metrics, used to distinguish metrics
+ * pooled from different processes / applications, so, eg what would
+ * be "cpu.svc" if this is NULL becomes "myapp.cpu.svc" is this is
+ * set to "myapp". Policies are applied using the name with the prefix,
+ * if present.
+ */
+#endif
+
/* Add new things just above here ---^
* This is part of the ABI, don't needlessly break compatibility
*
LWS_VISIBLE LWS_EXTERN void *
lws_context_user(struct lws_context *context);
+LWS_VISIBLE LWS_EXTERN const char *
+lws_vh_tag(struct lws_vhost *vh);
+
+/**
+ * lws_context_is_being_destroyed() - find out if context is being destroyed
+ *
+ * \param context: the struct lws_context pointer
+ *
+ * Returns nonzero if the context has had lws_context_destroy() called on it...
+ * when using event library loops the destroy process can be asynchronous. In
+ * the special case of libuv foreign loops, the failure to create the context
+ * may have to do work on the foreign loop to reverse the partial creation,
+ * meaning a failed context create cannot unpick what it did and return NULL.
+ *
+ * In that condition, a valid context that is already started the destroy
+ * process is returned, and this test api will return nonzero as a way to
+ * find out the create is in the middle of failing.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_context_is_being_destroyed(struct lws_context *context);
+
/*! \defgroup vhost-mounts Vhost mounts and options
* \ingroup context-and-vhost-creation
*
+++ /dev/null
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
- *
- * 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.
- *
- * included from libwebsockets.h
- */
-
-enum {
-
- /* types of latency, all nonblocking except name resolution */
-
- LDLT_READ, /* time taken to read LAT_DUR_PROXY_RX_TO_CLIENT_WRITE */
- LDLT_WRITE,
- LDLT_NAME_RESOLUTION, /* BLOCKING: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
- LDLT_CONNECTION, /* conn duration: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
- LDLT_TLS_NEG_CLIENT, /* tls conn duration: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
- LDLT_TLS_NEG_SERVER, /* tls conn duration: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
-
- LDLT_USER,
-
- /* interval / duration elements in latencies array */
-
- LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE = 0,
- /* us the client spent waiting to write to proxy */
- LAT_DUR_PROXY_CLIENT_WRITE_TO_PROXY_RX,
- /* us the packet took to be received by proxy */
- LAT_DUR_PROXY_PROXY_REQ_TO_WRITE,
- /* us the proxy has to wait before it could write */
- LAT_DUR_PROXY_RX_TO_ONWARD_TX,
- /* us the proxy spent waiting to write to destination, or
- * if nonproxied, then time between write request and write */
-
- LAT_DUR_USERCB, /* us duration of user callback */
-
- LAT_DUR_STEPS /* last */
-};
-
-typedef struct lws_detlat {
- lws_usec_t earliest_write_req;
- lws_usec_t earliest_write_req_pre_write;
- /**< use this for interval comparison */
- const char *aux; /* name for name resolution timing */
- int type;
- uint32_t latencies[LAT_DUR_STEPS];
- size_t req_size;
- size_t acc_size;
-} lws_detlat_t;
-
-typedef int (*det_lat_buf_cb_t)(struct lws_context *context,
- const lws_detlat_t *d);
-
-/**
- * lws_det_lat_cb() - inject your own latency records
- *
- * \param context: the lws_context
- * \param d: the lws_detlat_t you have prepared
- *
- * For proxying or similar cases where latency information is available from
- * user code rather than lws itself, you can generate your own latency callback
- * events with your own lws_detlat_t.
- */
-
-LWS_VISIBLE LWS_EXTERN int
-lws_det_lat_cb(struct lws_context *context, lws_detlat_t *d);
-
-/*
- * detailed_latency_plot_cb() - canned save to file in plottable format cb
- *
- * \p context: the lws_context
- * \p d: the detailed latency event information
- *
- * This canned callback makes it easy to export the detailed latency information
- * to a file. Just set the context creation members like this
- *
- * #if defined(LWS_WITH_DETAILED_LATENCY)
- * info.detailed_latency_cb = lws_det_lat_plot_cb;
- * info.detailed_latency_filepath = "/tmp/lws-latency-results";
- * #endif
- *
- * and you will get a file containing information like this
- *
- * 718823864615 N 10589 0 0 10589 0 0 0
- * 718823880837 C 16173 0 0 16173 0 0 0
- * 718823913063 T 32212 0 0 32212 0 0 0
- * 718823931835 r 0 0 0 0 232 30 256
- * 718823948757 r 0 0 0 0 40 30 256
- * 718823948799 r 0 0 0 0 83 30 256
- * 718823965602 r 0 0 0 0 27 30 256
- * 718823965617 r 0 0 0 0 43 30 256
- * 718823965998 r 0 0 0 0 12 28 256
- * 718823983887 r 0 0 0 0 74 3 4096
- * 718823986411 w 16 87 7 110 9 80 80
- * 718824006358 w 8 68 6 82 6 80 80
- *
- * which is easy to grep and pass to gnuplot.
- *
- * The columns are
- *
- * - unix time in us
- * - N = Name resolution, C = TCP Connection, T = TLS negotiation server,
- * t = TLS negotiation client, r = Read, w = Write
- * - us duration, for w time client spent waiting to write
- * - us duration, for w time data spent in transit to proxy
- * - us duration, for w time proxy waited to send data
- * - as a convenience, sum of last 3 columns above
- * - us duration, time spent in callback
- * - last 2 are actual / requested size in bytes
- */
-LWS_VISIBLE LWS_EXTERN int
-lws_det_lat_plot_cb(struct lws_context *context, const lws_detlat_t *d);
-
-/**
- * lws_det_lat_active() - indicates if latencies are being measured
- *
- * \context: lws_context
- *
- * Returns 0 if latency measurement has not been set up (the callback is NULL).
- * Otherwise returns 1
- */
-LWS_VISIBLE LWS_EXTERN int
-lws_det_lat_active(struct lws_context *context);
* will transition to use when it drops root privileges.
*/
LWS_VISIBLE LWS_EXTERN int
-lws_diskcache_prepare(const char *cache_base_dir, int mode, int uid);
+lws_diskcache_prepare(const char *cache_base_dir, int mode, uid_t uid);
#define LWS_DISKCACHE_QUERY_NO_CACHE 0
#define LWS_DISKCACHE_QUERY_EXISTS 1
--- /dev/null
+/*
+ * lws abstract display
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ */
+
+#if !defined(__LWS_DISPLAY_H__)
+#define __LWS_DISPLAY_H__
+
+#include <stdint.h>
+
+typedef uint16_t lws_display_scalar;
+
+/*
+ * This is embedded in the actual display implementation object at the top,
+ * so a pointer to this can be cast to a pointer to the implementation object
+ * by any code that is specific to how it was implemented.
+ *
+ * Notice for the backlight / display intensity we contain pwm_ops... these can
+ * be some other pwm_ops like existing gpio pwm ops, or handled in a customized
+ * way like set oled contrast. Either way, the pwm level is arrived at via a
+ * full set of lws_led_sequences capable of generic lws transitions
+ */
+
+typedef struct lws_display {
+ int (*init)(const struct lws_display *disp);
+ const lws_pwm_ops_t *bl_pwm_ops;
+ int (*contrast)(const struct lws_display *disp, uint8_t contrast);
+ int (*blit)(const struct lws_display *disp, const uint8_t *src,
+ lws_display_scalar x, lws_display_scalar y,
+ lws_display_scalar w, lws_display_scalar h);
+ int (*power)(const struct lws_display *disp, int state);
+
+ const lws_led_sequence_def_t *bl_active;
+ const lws_led_sequence_def_t *bl_dim;
+ const lws_led_sequence_def_t *bl_transition;
+
+ void *variant;
+
+ int bl_index;
+
+ lws_display_scalar w;
+ /**< display surface width in pixels */
+ lws_display_scalar h;
+ /**< display surface height in pixels */
+
+ uint8_t latency_wake_ms;
+ /**< ms required after wake from sleep before display usable again...
+ * delay bringing up the backlight for this amount of time on wake.
+ * This is managed via a sul on the event loop, not blocking. */
+} lws_display_t;
+
+/*
+ * This contains dynamic data related to display state
+ */
+
+enum lws_display_controller_state {
+ LWSDISPS_OFF,
+ LWSDISPS_AUTODIMMED, /* is in pre- blanking static dim mode */
+ LWSDISPS_BECOMING_ACTIVE, /* waiting for wake latency before active */
+ LWSDISPS_ACTIVE, /* is active */
+ LWSDISPS_GOING_OFF /* dimming then off */
+};
+
+typedef struct lws_display_state {
+
+ lws_sorted_usec_list_t sul_autodim;
+ const lws_display_t *disp;
+ struct lws_context *ctx;
+
+ int autodim_ms;
+ int off_ms;
+
+ struct lws_led_state *bl_lcs;
+
+ lws_led_state_chs_t chs;
+ /* set of sequencer transition channels */
+
+ enum lws_display_controller_state state;
+
+} lws_display_state_t;
+
+/**
+ * lws_display_state_init() - initialize display states
+ *
+ * \param lds: the display state object
+ * \param ctx: the lws context
+ * \param autodim_ms: ms since last active report to dim display (<0 = never)
+ * \param off_ms: ms since dim to turn display off (<0 = never)
+ * \param bl_lcs: the led controller instance that has the backlight
+ * \param disp: generic display object we belong to
+ *
+ * This initializes a display's state, and sets up the optional screen auto-dim
+ * and blanking on inactive, and gradual brightness change timer.
+ *
+ * - auto-dim then off: set autodim to some ms and off_ms to some ms
+ * - auto-dim only: set autodim to some ms and off_ms to -1
+ * - off-only: set autodim to some ms and off_ms to 0
+ * - neither: set both autodim and off_ms to -1
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_display_state_init(lws_display_state_t *lds, struct lws_context *ctx,
+ int autodim_ms, int off_ms, struct lws_led_state *bl_lcs,
+ const lws_display_t *disp);
+
+/**
+ * lws_display_state_set_brightness() - gradually change the brightness
+ *
+ * \param lds: the display state we are changing
+ * \param target: the target brightness to transition to
+ *
+ * Adjusts the brightness gradually twoards the target at 20Hz
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_display_state_set_brightness(lws_display_state_t *lds,
+ const lws_led_sequence_def_t *pwmseq);
+
+/*
+ * lws_display_state_active() - inform the system the display is active
+ *
+ * \param lds: the display state we are marking as active
+ *
+ * Resets the auto-dim and auto-off timers and makes sure the display is on and
+ * at the active brightness level
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_display_state_active(lws_display_state_t *lds);
+
+/*
+ * lws_display_state_off() - turns off the related display
+ *
+ * \param lds: the display state we are turning off
+ *
+ * Turns the display to least power mode or completely off if possible.
+ * Disables the timers related to dimming and blanking.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_display_state_off(lws_display_state_t *lds);
+
+#endif
* doubly linked-list
*/
-#if defined (LWS_WITH_DEPRECATED_LWS_DLL)
-
-/*
- * This is going away in v4.1. You can set the cmake option above to keep it
- * around temporarily. Migrate your stuff to the more capable and robust
- * lws_dll2 below
- */
-
-struct lws_dll {
- struct lws_dll *prev;
- struct lws_dll *next;
-};
-
-/*
- * these all point to the composed list objects... you have to use the
- * lws_container_of() helper to recover the start of the containing struct
- */
-
-#define lws_dll_add_front lws_dll_add_head
-
-LWS_VISIBLE LWS_EXTERN void
-lws_dll_add_head(struct lws_dll *d, struct lws_dll *phead);
-
-LWS_VISIBLE LWS_EXTERN void
-lws_dll_add_tail(struct lws_dll *d, struct lws_dll *phead);
-
-LWS_VISIBLE LWS_EXTERN void
-lws_dll_insert(struct lws_dll *d, struct lws_dll *target,
- struct lws_dll *phead, int before);
-
-static LWS_INLINE struct lws_dll *
-lws_dll_get_head(struct lws_dll *phead) { return phead->next; }
-
-static LWS_INLINE struct lws_dll *
-lws_dll_get_tail(struct lws_dll *phead) { return phead->prev; }
-
-/*
- * caution, this doesn't track the tail in the head struct. Use
- * lws_dll_remove_track_tail() instead of this if you want tail tracking. Using
- * this means you can't use lws_dll_add_tail() amd
- */
-LWS_VISIBLE LWS_EXTERN void
-lws_dll_remove(struct lws_dll *d) LWS_WARN_DEPRECATED;
-
-LWS_VISIBLE LWS_EXTERN void
-lws_dll_remove_track_tail(struct lws_dll *d, struct lws_dll *phead);
-
-/* another way to do lws_start_foreach_dll_safe() on a list via a cb */
-
-LWS_VISIBLE LWS_EXTERN int
-lws_dll_foreach_safe(struct lws_dll *phead, void *user,
- int (*cb)(struct lws_dll *d, void *user));
-
-#define lws_dll_is_detached(___dll, __head) \
- (!(___dll)->prev && !(___dll)->next && (__head)->prev != (___dll))
-
-#endif
-
/*
* lws_dll2_owner / lws_dll2 : more capable version of lws_dll. Differences:
*
uint32_t count;
} lws_dll2_owner_t;
-static LWS_INLINE int
-lws_dll2_is_detached(const struct lws_dll2 *d) { return !d->owner; }
+LWS_VISIBLE LWS_EXTERN int
+lws_dll2_is_detached(const struct lws_dll2 *d);
static LWS_INLINE const struct lws_dll2_owner *
lws_dll2_owner(const struct lws_dll2 *d) { return d->owner; }
lws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own,
int (*compare)(const lws_dll2_t *d, const lws_dll2_t *i));
+LWS_VISIBLE LWS_EXTERN void
+lws_dll2_add_sorted_priv(lws_dll2_t *d, lws_dll2_owner_t *own, void *priv,
+ int (*compare3)(void *priv, const lws_dll2_t *d,
+ const lws_dll2_t *i));
+
+LWS_VISIBLE LWS_EXTERN void *
+_lws_dll2_search_sz_pl(lws_dll2_owner_t *own, const char *name, size_t namelen,
+ size_t dll2_ofs, size_t ptr_ofs);
+
+/*
+ * Searches objects in an owner list linearly and returns one with a given
+ * member C-string matching a supplied length-provided string if it exists, else
+ * NULL.
+ */
+
+#define lws_dll2_search_sz_pl(own, name, namelen, type, membd2list, membptr) \
+ ((type *)_lws_dll2_search_sz_pl(own, name, namelen, \
+ offsetof(type, membd2list), \
+ offsetof(type, membptr)))
+
#if defined(_DEBUG)
void
lws_dll2_describe(struct lws_dll2_owner *owner, const char *desc);
LWS_VISIBLE LWS_EXTERN void
lws_dsh_free(void **obj);
+LWS_VISIBLE LWS_EXTERN size_t
+lws_dsh_get_size(struct lws_dsh *dsh, int kind);
+
/**
* lws_dsh_get_head() - get the head allocation inside the dsh
*
+++ /dev/null
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
- *
- * 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.
- *
- * This is only included from libwebsockets.h if LWS_WITH_ESP32
- */
-
-/* ESP32 helper declarations */
-
-#include <mdns.h>
-#include <esp_partition.h>
-
-#define LWS_PLUGIN_STATIC
-#define LWS_MAGIC_REBOOT_TYPE_ADS 0x50001ffc
-#define LWS_MAGIC_REBOOT_TYPE_REQ_FACTORY 0xb00bcafe
-#define LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY 0xfaceb00b
-#define LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON 0xf0cedfac
-#define LWS_MAGIC_REBOOT_TYPE_REQ_FACTORY_ERASE_OTA 0xfac0eeee
-
-/* user code provides these */
-
-extern void
-lws_esp32_identify_physical_device(void);
-
-/* lws-plat-esp32 provides these */
-
-typedef void (*lws_cb_scan_done)(uint16_t count, wifi_ap_record_t *recs, void *arg);
-
-enum genled_state {
- LWSESP32_GENLED__INIT,
- LWSESP32_GENLED__LOST_NETWORK,
- LWSESP32_GENLED__NO_NETWORK,
- LWSESP32_GENLED__CONN_AP,
- LWSESP32_GENLED__GOT_IP,
- LWSESP32_GENLED__OK,
-};
-
-struct lws_group_member {
- struct lws_group_member *next;
- uint64_t last_seen;
- char model[16];
- char role[16];
- char host[32];
- char mac[20];
- int width, height;
- struct ip4_addr addr;
- struct ip6_addr addrv6;
- uint8_t flags;
-};
-
-#define LWS_SYSTEM_GROUP_MEMBER_ADD 1
-#define LWS_SYSTEM_GROUP_MEMBER_CHANGE 2
-#define LWS_SYSTEM_GROUP_MEMBER_REMOVE 3
-
-#define LWS_GROUP_FLAG_SELF 1
-
-struct lws_esp32 {
- char sta_ip[16];
- char sta_mask[16];
- char sta_gw[16];
- char serial[16];
- char opts[16];
- char model[16];
- char group[16];
- char role[16];
- char ssid[4][64];
- char password[4][64];
- char active_ssid[64];
- char access_pw[16];
- char hostname[32];
- char mac[20];
- char le_dns[64];
- char le_email[64];
- char region;
- char inet;
- char conn_ap;
-
- enum genled_state genled;
- uint64_t genled_t;
-
- lws_cb_scan_done scan_consumer;
- void *scan_consumer_arg;
- struct lws_group_member *first;
- int extant_group_members;
-
- char acme;
- char upload;
-
- volatile char button_is_down;
-};
-
-struct lws_esp32_image {
- uint32_t romfs;
- uint32_t romfs_len;
- uint32_t json;
- uint32_t json_len;
-};
-
-extern struct lws_esp32 lws_esp32;
-struct lws_vhost;
-
-extern esp_err_t
-lws_esp32_event_passthru(void *ctx, system_event_t *event);
-extern void
-lws_esp32_wlan_config(void);
-extern void
-lws_esp32_wlan_start_ap(void);
-extern void
-lws_esp32_wlan_start_station(void);
-struct lws_context_creation_info;
-extern void
-lws_esp32_set_creation_defaults(struct lws_context_creation_info *info);
-extern struct lws_context *
-lws_esp32_init(struct lws_context_creation_info *, struct lws_vhost **pvh);
-extern int
-lws_esp32_wlan_nvs_get(int retry);
-extern esp_err_t
-lws_nvs_set_str(nvs_handle handle, const char* key, const char* value);
-extern void
-lws_esp32_restart_guided(uint32_t type);
-extern const esp_partition_t *
-lws_esp_ota_get_boot_partition(void);
-extern int
-lws_esp32_get_image_info(const esp_partition_t *part, struct lws_esp32_image *i, char *json, int json_len);
-extern int
-lws_esp32_leds_network_indication(void);
-
-extern uint32_t lws_esp32_get_reboot_type(void);
-extern uint16_t lws_esp32_sine_interp(int n);
-
-/* required in external code by esp32 plat (may just return if no leds) */
-extern void lws_esp32_leds_timer_cb(TimerHandle_t th);
--- /dev/null
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * These are exports needed by event lib plugins.
+ *
+ * You should consider these opaque for normal user code.
+ */
+
+LWS_VISIBLE LWS_EXTERN void *
+lws_realloc(void *ptr, size_t size, const char *reason);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_vhost_destroy1(struct lws_vhost *vh);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason,
+ const char *caller);
+
+struct lws_context_per_thread;
+LWS_VISIBLE LWS_EXTERN void
+lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt);
+
+#if !defined(wsi_from_fd) && !defined(WIN32) && !defined(_WIN32)
+struct lws_context;
+LWS_VISIBLE LWS_EXTERN struct lws *
+wsi_from_fd(const struct lws_context *context, int fd);
+#endif
+
+LWS_VISIBLE LWS_EXTERN int
+_lws_plat_service_forced_tsi(struct lws_context *context, int tsi);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_context_destroy2(struct lws_context *context);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_destroy_event_pipe(struct lws *wsi);
+
+LWS_VISIBLE LWS_EXTERN void
+__lws_close_free_wsi_final(struct lws *wsi);
+
+#if LWS_MAX_SMP > 1
+
+struct lws_mutex_refcount {
+ pthread_mutex_t lock;
+ pthread_t lock_owner;
+ const char *last_lock_reason;
+ char lock_depth;
+ char metadata;
+};
+
+LWS_VISIBLE LWS_EXTERN void
+lws_mutex_refcount_assert_held(struct lws_mutex_refcount *mr);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_mutex_refcount_init(struct lws_mutex_refcount *mr);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_mutex_refcount_destroy(struct lws_mutex_refcount *mr);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_mutex_refcount_lock(struct lws_mutex_refcount *mr, const char *reason);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_mutex_refcount_unlock(struct lws_mutex_refcount *mr);
+
+#endif
--- /dev/null
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * Fault injection api if built with LWS_WITH_SYS_FAULT_INJECTION
+ */
+
+typedef struct lws_xos {
+ uint64_t s[4];
+} lws_xos_t;
+
+/**
+ * lws_xos_init() - seed xoshiro256 PRNG
+ *
+ * \param xos: the prng state object to initialize
+ * \param seed: the 64-bit seed
+ *
+ * Initialize PRNG \xos with the starting state represented by \p seed
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_xos_init(struct lws_xos *xos, uint64_t seed);
+
+/**
+ * lws_xos() - get next xoshiro256 PRNG result and update state
+ *
+ * \param xos: the PRNG state to use
+ *
+ * Returns next 64-bit PRNG result. These are cheap to get,
+ * quite a white noise sequence, and completely deterministic
+ * according to the seed it was initialized with.
+ */
+LWS_VISIBLE LWS_EXTERN uint64_t LWS_WARN_UNUSED_RESULT
+lws_xos(struct lws_xos *xos);
+
+/**
+ * lws_xos_percent() - return 1 a given percent of the time on average
+ *
+ * \param xos: the PRNG state to use
+ * \param percent: chance in 100 of returning 1
+ *
+ * Returns 1 if next random % 100 is < \p percent, such that
+ * 100 always returns 1, 0 never returns 1, and the chance linearly scales
+ * inbetween
+ */
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_xos_percent(struct lws_xos *xos, int percent);
+
+#if defined(LWS_WITH_SYS_FAULT_INJECTION)
+
+enum {
+ LWSFI_ALWAYS,
+ LWSFI_DETERMINISTIC, /* do .count injections after .pre then stop */
+ LWSFI_PROBABILISTIC, /* .pre % chance of injection */
+ LWSFI_PATTERN, /* use .count bits in .pattern after .pre */
+ LWSFI_PATTERN_ALLOC, /* as _PATTERN, but .pattern is malloc'd */
+};
+
+typedef struct lws_fi {
+ const char *name;
+ const uint8_t *pattern;
+ uint64_t pre;
+ uint64_t count;
+ uint64_t times; /* start at 0, tracks usage */
+ char type; /* LWSFI_* */
+} lws_fi_t;
+
+typedef struct lws_fi_ctx {
+ lws_dll2_owner_t fi_owner;
+ struct lws_xos xos;
+ const char *name;
+} lws_fi_ctx_t;
+
+/**
+ * lws_fi() - find out if we should perform the named fault injection this time
+ *
+ * \param fic: fault injection tracking context
+ * \param fi_name: name of fault injection
+ *
+ * This checks if the named fault is configured in the fi tracking context
+ * provided, if it is, then it will make a decision if the named fault should
+ * be applied this time, using the tracking in the named lws_fi_t.
+ *
+ * If the provided context has a parent, that is also checked for the named fi
+ * item recursively, with the first found being used to determine if to inject
+ * or not.
+ *
+ * If LWS_WITH_SYS_FAULT_INJECTION is not defined, then this always return 0.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_fi(const lws_fi_ctx_t *fic, const char *fi_name);
+
+/**
+ * lws_fi_add() - add an allocated copy of fault injection to a context
+ *
+ * \param fic: fault injection tracking context
+ * \param fi: the fault injection details
+ *
+ * This allocates a copy of \p fi and attaches it to the fault injection context
+ * \p fic. \p fi can go out of scope after this safely.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_fi_add(lws_fi_ctx_t *fic, const lws_fi_t *fi);
+
+/**
+ * lws_fi_remove() - remove an allocated copy of fault injection from a context
+ *
+ * \param fic: fault injection tracking context
+ * \param name: the fault injection name to remove
+ *
+ * This looks for the named fault injection and removes and destroys it from
+ * the specified fault injection context
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_fi_remove(lws_fi_ctx_t *fic, const char *name);
+
+/**
+ * lws_fi_import() - transfers all the faults from one context to another
+ *
+ * \param fic_dest: the fault context to receive the faults
+ * \param fic_src: the fault context that will be emptied out into \p fic_dest
+ *
+ * This is used to initialize created object fault injection contexts from
+ * the caller.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_fi_import(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src);
+
+/**
+ * lws_fi_inherit_copy() - attach copies of matching fault injection objects to dest
+ *
+ * \param fic_dest: destination Fault Injection context
+ * \param fic_src: parent fault context that may contain matching rules
+ * \param scope: the name of the path match required, eg, "vh"
+ * \param value: the dynamic name of our match, eg, "myvhost"
+ *
+ * If called with scope "vh" and value "myvhost", then matches faults starting
+ * "vh=myvhost/", strips that part of the name if it matches and makes a copy
+ * of the rule with the modified name attached to the destination Fault Injection
+ * context.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_fi_inherit_copy(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src,
+ const char *scope, const char *value);
+
+/**
+ * lws_fi_destroy() - removes all allocated fault injection entries
+ *
+ * \param fic: fault injection tracking context
+ *
+ * This walks any allocated fault injection entries in \p fic and detaches and
+ * destroys them. It doesn't try to destroc \p fic itself, since this is
+ * not usually directly allocated.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_fi_destroy(const lws_fi_ctx_t *fic);
+
+/**
+ * lws_fi_deserialize() - adds fault in string form to Fault Injection Context
+ *
+ * \p fic: the fault injection context
+ * \p sers: the string serializing the desired fault details
+ *
+ * This turns a string like "ss=captive_portal_detect/wsi/dnsfail(10%)" into
+ * a fault injection struct added to the fault injection context \p fic
+ *
+ * You can prepare the context creation info .fic with these before creating
+ * the context, and use namespace paths on those to target other objects.
+ */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_fi_deserialize(lws_fi_ctx_t *fic, const char *sers);
+
+LWS_VISIBLE LWS_EXTERN int
+_lws_fi_user_wsi_fi(struct lws *wsi, const char *name);
+LWS_VISIBLE LWS_EXTERN int
+_lws_fi_user_context_fi(struct lws_context *ctx, const char *name);
+
+#if defined(LWS_WITH_SECURE_STREAMS)
+struct lws_ss_handle;
+LWS_VISIBLE LWS_EXTERN int
+_lws_fi_user_ss_fi(struct lws_ss_handle *h, const char *name);
+#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
+struct lws_sspc_handle;
+LWS_VISIBLE LWS_EXTERN int
+_lws_fi_user_sspc_fi(struct lws_sspc_handle *h, const char *name);
+#endif
+#endif
+
+#define lws_fi_user_wsi_fi(_wsi, _name) _lws_fi_user_wsi_fi(_wsi, _name)
+#define lws_fi_user_context_fi(_ctx, _name) _lws_fi_user_context_fi(_ctx, _name)
+#define lws_fi_user_ss_fi(_h, _name) _lws_fi_user_ss_fi(_h, _name)
+#define lws_fi_user_sspc_fi(_h, _name) _lws_fi_user_sspc_fi(_h, _name)
+
+#else
+
+/*
+ * Helper so we can leave lws_fi() calls embedded in the code being tested,
+ * if fault injection is not enabled then it just always says "no" at buildtime.
+ */
+
+#define lws_fi(_fi_name, _fic) (0)
+#define lws_fi_destroy(_x)
+#define lws_fi_inherit_copy(_a, _b, _c, _d)
+#define lws_fi_deserialize(_x, _y)
+#define lws_fi_user_wsi_fi(_wsi, _name) (0)
+#define lws_fi_user_context_fi(_wsi, _name) (0)
+#define lws_fi_user_ss_fi(_h, _name) (0)
+#define lws_fi_user_sspc_fi(_h, _name) (0)
+
+#endif
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
-#include "esp_event_loop.h"
+//#include "esp_event_loop.h"
#include "nvs.h"
#include "driver/gpio.h"
#include "esp_spi_flash.h"
#include "freertos/timers.h"
+
+#if defined(LWS_ESP_PLATFORM)
+#include "lwip/sockets.h"
+#include "lwip/netdb.h"
+#if defined(LWS_WITH_DRIVERS)
+#include "libwebsockets/lws-gpio.h"
+extern const lws_gpio_ops_t lws_gpio_plat;
+#endif
+#endif
+
#endif /* LWS_AMAZON_RTOS */
#if !defined(CONFIG_FREERTOS_HZ)
* \param context: your lws_context (for RNG access)
* \param curve_table: NULL, enabling P-256, P-384 and P-521, or a replacement
* struct lws_ec_curves array, terminated by an entry with
- * .name = NULL, of curves you want to whitelist
+ * .name = NULL, of curves you want to allow
*
* Initializes a genecdh
*/
* \param context: your lws_context (for RNG access)
* \param curve_table: NULL, enabling P-256, P-384 and P-521, or a replacement
* struct lws_ec_curves array, terminated by an entry with
- * .name = NULL, of curves you want to whitelist
+ * .name = NULL, of curves you want to allow
*
* Initializes a genecdh
*/
mbedtls_md_context_t ctx;
#else
const EVP_MD *evp_type;
+
+#if defined(LWS_HAVE_EVP_PKEY_new_raw_private_key)
+ EVP_MD_CTX *ctx;
+ EVP_PKEY *key;
+#else
#if defined(LWS_HAVE_HMAC_CTX_new)
HMAC_CTX *ctx;
#else
HMAC_CTX ctx;
#endif
#endif
+
+#endif
};
/** lws_genhash_size() - get hash size in bytes
--- /dev/null
+/*
+ * Generic GPIO ops
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * This is like an abstract class for gpio, a real implementation provides
+ * functions for the ops that use the underlying OS gpio arrangements.
+ */
+
+#if !defined(__LWS_GPIO_H__)
+#define __LWS_GPIO_H__
+
+typedef int _lws_plat_gpio_t;
+
+typedef enum {
+ LWSGGPIO_IRQ_NONE,
+ LWSGGPIO_IRQ_RISING,
+ LWSGGPIO_IRQ_FALLING,
+ LWSGGPIO_IRQ_CHANGE,
+ LWSGGPIO_IRQ_LOW,
+ LWSGGPIO_IRQ_HIGH
+} lws_gpio_irq_t;
+
+enum {
+ LWSGGPIO_FL_READ = (1 << 0),
+ LWSGGPIO_FL_WRITE = (1 << 1),
+ LWSGGPIO_FL_PULLUP = (1 << 2),
+ LWSGGPIO_FL_PULLDOWN = (1 << 3),
+ LWSGGPIO_FL_START_LOW = (1 << 4),
+};
+
+typedef void (*lws_gpio_irq_cb_t)(void *arg);
+
+typedef struct lws_gpio_ops {
+ void (*mode)(_lws_plat_gpio_t gpio, int flags);
+ int (*read)(_lws_plat_gpio_t gpio);
+ void (*set)(_lws_plat_gpio_t gpio, int val);
+ int (*irq_mode)(_lws_plat_gpio_t gpio, lws_gpio_irq_t irq,
+ lws_gpio_irq_cb_t cb, void *arg);
+} lws_gpio_ops_t;
+
+#endif
/*
* libwebsockets - small server side websockets and web server implementation
*
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
enum lws_token_indexes {
WSI_TOKEN_GET_URI, /* 0 */
WSI_TOKEN_POST_URI,
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_OPTIONS_URI,
#endif
WSI_TOKEN_HOST,
WSI_TOKEN_CONNECTION,
WSI_TOKEN_UPGRADE, /* 5 */
WSI_TOKEN_ORIGIN,
-#if defined(LWS_ROLE_WS)
+#if defined(LWS_ROLE_WS) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_DRAFT,
#endif
WSI_TOKEN_CHALLENGE,
-#if defined(LWS_ROLE_WS)
+#if defined(LWS_ROLE_WS) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_EXTENSIONS,
WSI_TOKEN_KEY1, /* 10 */
WSI_TOKEN_KEY2,
WSI_TOKEN_NONCE,
#endif
WSI_TOKEN_HTTP,
-#if defined(LWS_ROLE_H2)
+#if defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_HTTP2_SETTINGS, /* 16 */
#endif
WSI_TOKEN_HTTP_ACCEPT,
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_HTTP_AC_REQUEST_HEADERS,
#endif
WSI_TOKEN_HTTP_IF_MODIFIED_SINCE,
WSI_TOKEN_HTTP_CONTENT_TYPE,
WSI_TOKEN_HTTP_DATE,
WSI_TOKEN_HTTP_RANGE,
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_HTTP_REFERER,
#endif
-#if defined(LWS_ROLE_WS)
+#if defined(LWS_ROLE_WS) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_KEY,
WSI_TOKEN_VERSION,
WSI_TOKEN_SWORIGIN,
#endif
-#if defined(LWS_ROLE_H2)
+#if defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_HTTP_COLON_AUTHORITY,
WSI_TOKEN_HTTP_COLON_METHOD,
WSI_TOKEN_HTTP_COLON_PATH,
WSI_TOKEN_HTTP_COLON_STATUS,
#endif
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_HTTP_ACCEPT_CHARSET,
#endif
WSI_TOKEN_HTTP_ACCEPT_RANGES,
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN,
#endif
WSI_TOKEN_HTTP_AGE,
WSI_TOKEN_HTTP_LAST_MODIFIED,
WSI_TOKEN_HTTP_LINK,
WSI_TOKEN_HTTP_LOCATION,
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_HTTP_MAX_FORWARDS,
WSI_TOKEN_HTTP_PROXY_AUTHENTICATE,
WSI_TOKEN_HTTP_PROXY_AUTHORIZATION,
WSI_TOKEN_HTTP_RETRY_AFTER,
WSI_TOKEN_HTTP_SERVER,
WSI_TOKEN_HTTP_SET_COOKIE,
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY,
#endif
WSI_TOKEN_HTTP_TRANSFER_ENCODING,
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_HTTP_USER_AGENT,
WSI_TOKEN_HTTP_VARY,
WSI_TOKEN_HTTP_VIA,
WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
#endif
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_PATCH_URI,
WSI_TOKEN_PUT_URI,
WSI_TOKEN_DELETE_URI,
#endif
WSI_TOKEN_HTTP_URI_ARGS,
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_PROXY,
WSI_TOKEN_HTTP_X_REAL_IP,
#endif
WSI_TOKEN_X_FORWARDED_FOR,
WSI_TOKEN_CONNECT,
WSI_TOKEN_HEAD_URI,
-#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2)
+#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_TE,
WSI_TOKEN_REPLAY_NONCE, /* ACME */
#endif
-#if defined(LWS_ROLE_H2)
+#if defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_COLON_PROTOCOL,
#endif
WSI_TOKEN_X_AUTH_TOKEN,
+ WSI_TOKEN_DSS_SIGNATURE,
/****** add new things just above ---^ ******/
/* parser state additions, no storage associated */
WSI_TOKEN_NAME_PART,
-#if defined(LWS_WITH_CUSTOM_HEADERS)
+#if defined(LWS_WITH_CUSTOM_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
WSI_TOKEN_UNKNOWN_VALUE_PART,
#endif
WSI_TOKEN_SKIPPING,
int nlen);
/**
+ * lws_get_urlarg_by_name_safe() - get copy and return length of y for x=y urlargs
+ *
+ * \param wsi: the connection to check
+ * \param name: the arg name, like "token" or "token="
+ * \param buf: the buffer to receive the urlarg (including the name= part)
+ * \param len: the length of the buffer to receive the urlarg
+ *
+ * Returns -1 if not present, else the length of y in the urlarg name=y. If
+ * zero or greater, then buf contains a copy of the string y. Any = after the
+ * name match is trimmed off if the name does not end with = itself.
+ *
+ * This returns the explicit length and so can deal with binary blobs that are
+ * percent-encoded. It also makes sure buf has a NUL just after the valid
+ * length so it can work with NUL-based apis if you don't care about truncation.
+ *
+ * buf may have been written even when -1 is returned indicating no match.
+ *
+ * Use this in place of lws_get_urlarg_by_name() that does not return an
+ * explicit length.
+ *
+ * Use lws_get_urlarg_by_name_safe() instead of this, which returns the length.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_get_urlarg_by_name_safe(struct lws *wsi, const char *name, char *buf, int len);
+
+/**
* lws_get_urlarg_by_name() - return pointer to arg value if present
+ *
* \param wsi: the connection to check
* \param name: the arg name, like "token="
* \param buf: the buffer to receive the urlarg (including the name= part)
*
* Returns NULL if not found or a pointer inside buf to just after the
* name= part.
+ *
+ * This assumed the argument can be represented with a NUL-terminated string.
+ * It can't correctly deal with binary values encoded with %XX, eg. %00 will
+ * be understood to terminate the string.
+ *
+ * Use lws_get_urlarg_by_name_safe() instead of this, which returns the length.
*/
LWS_VISIBLE LWS_EXTERN const char *
-lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len);
+lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len)
+/* LWS_WARN_DEPRECATED */;
///@}
/*! \defgroup HTTP-headers-create HTTP headers: create
* lws_add_http_header_by_name() - append named header and value
*
* \param wsi: the connection to check
- * \param name: the hdr name, like "my-header"
+ * \param name: the hdr name, like "my-header:"
* \param value: the value after the = for this header
* \param length: the length of the value
* \param p: pointer to current position in buffer pointer
///@}
/**
+ * lws_http_date_render_from_unix() - render unixtime as RFC7231 date string
+ *
+ * \param buf: Destination string buffer
+ * \param len: avilable length of dest string buffer in bytes
+ * \param t: pointer to the time_t to render
+ *
+ * Returns 0 if time_t is rendered into the string buffer successfully, else
+ * nonzero.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_http_date_render_from_unix(char *buf, size_t len, const time_t *t);
+
+/**
+ * lws_http_date_parse_unix() - parse a RFC7231 date string into unixtime
+ *
+ * \param b: Source string buffer
+ * \param len: avilable length of source string buffer in bytes
+ * \param t: pointer to the destination time_t to set
+ *
+ * Returns 0 if string buffer parsed as RFC7231 time successfully, and
+ * *t set to the parsed unixtime, else return nonzero.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_http_date_parse_unix(const char *b, size_t len, time_t *t);
+
+/**
+ * lws_http_check_retry_after() - increase a timeout if retry-after present
+ *
+ * \param wsi: http stream this relates to
+ * \param us_interval_in_out: default us retry interval on entry may be updated
+ *
+ * This function may extend the incoming retry interval if the server has
+ * requested that using retry-after: header. It won't reduce the incoming
+ * retry interval, only leave it alone or increase it.
+ *
+ * *us_interval_in_out should be set to a default retry interval on entry, if
+ * the wsi has a retry-after time or interval that resolves to an interval
+ * longer than the entry *us_interval_in_out, that will be updated to the longer
+ * interval and return 0.
+ *
+ * If no usable retry-after or the time is now or in the past,
+ * *us_interval_in_out is left alone and the function returns nonzero.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_http_check_retry_after(struct lws *wsi, lws_usec_t *us_interval_in_out);
+
+/**
* lws_return_http_status() - Return simple http status
* \param wsi: Websocket instance (available from user callback)
* \param code: Status index, eg, 404
lws_http_is_redirected_to_get(struct lws *wsi);
/**
+ * lws_http_cookie_get() - return copy of named cookie if present
+ *
+ * \param wsi: the wsi to check
+ * \param name: name of the cookie
+ * \param buf: buffer to store the cookie contents into
+ * \param max_len: on entry, maximum length of buf... on exit, used len of buf
+ *
+ * If no cookie header, or no cookie of the requested name, or the value is
+ * larger than can fit in buf, returns nonzero.
+ *
+ * If the cookie is found, copies its value into buf with a terminating NUL,
+ * sets *max_len to the used length, and returns 0.
+ *
+ * This handles the parsing of the possibly multi-cookie header string and
+ * terminating the requested cookie at the next ; if present.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_http_cookie_get(struct lws *wsi, const char *name, char *buf, size_t *max);
+
+/**
+ * lws_http_client_http_error() - determine if the response code indicates an error
+ *
+ * \param code: the response code to test
+ *
+ * Returns nonzero if the code indicates an error, else zero if reflects a
+ * non-error condition
+ */
+#define lws_http_client_http_resp_is_error(code) (!(code < 400))
+
+/**
* lws_h2_update_peer_txcredit() - manually update stream peer tx credit
*
* \param wsi: the h2 child stream whose peer credit to change
*/
#define LWS_H2_STREAM_SID -1
LWS_VISIBLE LWS_EXTERN int
-lws_h2_update_peer_txcredit(struct lws *wsi, int sid, int bump);
+lws_h2_update_peer_txcredit(struct lws *wsi, unsigned int sid, int bump);
/**
--- /dev/null
+/*
+ * Generic I2C ops
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * This is like an abstract class for i2c, a real implementation provides
+ * functions for the ops that use the underlying OS arrangements.
+ */
+
+#if !defined(__LWS_I2C_H__)
+#define __LWS_I2C_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef struct lws_i2c_ops {
+ int (*init)(const struct lws_i2c_ops *ctx);
+ int (*start)(const struct lws_i2c_ops *ctx);
+ void (*stop)(const struct lws_i2c_ops *ctx);
+ int (*write)(const struct lws_i2c_ops *ctx, uint8_t data);
+ int (*read)(const struct lws_i2c_ops *ctx);
+ void (*set_ack)(const struct lws_i2c_ops *octx, int ack);
+} lws_i2c_ops_t;
+
+/*
+ * These are implemented by calling the ops above, and so are generic
+ */
+
+LWS_VISIBLE LWS_EXTERN int
+lws_i2c_command(const lws_i2c_ops_t *ctx, uint8_t ads7, uint8_t c);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_i2c_command_list(const lws_i2c_ops_t *ctx, uint8_t ads7, const uint8_t *buf,
+ size_t len);
+
+#endif
--- /dev/null
+/*
+ * lws abstract display implementation for ili9341 on spi
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ */
+
+#if !defined(__LWS_DISPLAY_ILI9341_SPI_H__)
+#define __LWS_DISPLAY_ILI9341_SPI_H__
+
+
+typedef struct lws_display_ili9341 {
+
+ lws_display_t disp; /* use lws_display_ili9341_ops to set */
+ const lws_spi_ops_t *spi; /* spi ops */
+
+ const lws_gpio_ops_t *gpio; /* NULL or gpio ops */
+ _lws_plat_gpio_t reset_gpio; /* if gpio ops, nReset gpio # */
+
+ uint8_t spi_index; /* cs index starting from 0 */
+
+} lws_display_ili9341_t;
+
+int
+lws_display_ili9341_spi_init(const struct lws_display *disp);
+int
+lws_display_ili9341_spi_blit(const struct lws_display *disp, const uint8_t *src,
+ lws_display_scalar x, lws_display_scalar y,
+ lws_display_scalar w, lws_display_scalar h);
+int
+lws_display_ili9341_spi_power(const struct lws_display *disp, int state);
+
+#define lws_display_ili9341_ops \
+ .init = lws_display_ili9341_spi_init, \
+ .blit = lws_display_ili9341_spi_blit, \
+ .power = lws_display_ili9341_spi_power
+#endif
* Returns either -1 if problems, or the number of bytes written to \p out.
* If the section is not the first one, '.' is prepended.
*/
-
LWS_VISIBLE LWS_EXTERN int
lws_jws_encode_section(const char *in, size_t in_len, int first, char **p,
char *end);
+
+/**
+ * lws_jwt_signed_validate() - check a compact JWT against a key and alg
+ *
+ * \param ctx: the lws_context
+ * \param jwk: the key for checking the signature
+ * \param alg_list: the expected alg name, like "ES512"
+ * \param com: the compact JWT
+ * \param len: the length of com
+ * \param temp: a temp scratchpad
+ * \param tl: available length of temp scratchpad
+ * \param out: the output buffer to hold the validated plaintext
+ * \param out_len: on entry, max length of out; on exit, used length of out
+ *
+ * Returns nonzero if the JWT cannot be validated or the plaintext can't fit the
+ * provided output buffer, or 0 if it is validated as being signed by the
+ * provided jwk.
+ *
+ * If validated, the plaintext in the JWT is copied into out and out_len set to
+ * the used length.
+ *
+ * temp can be discarded or reused after the call returned, it's used to hold
+ * transformations of the B64 JWS in the JWT.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_jwt_signed_validate(struct lws_context *ctx, struct lws_jwk *jwk,
+ const char *alg_list, const char *com, size_t len,
+ char *temp, int tl, char *out, size_t *out_len);
+
+/**
+ * lws_jwt_sign_compact() - generate a compact JWT using a key and alg
+ *
+ * \param ctx: the lws_context
+ * \param jwk: the signing key
+ * \param alg: the signing alg name, like "ES512"
+ * \param out: the output buffer to hold the signed JWT in compact form
+ * \param out_len: on entry, the length of out; on exit, the used amount of out
+ * \param temp: a temp scratchpad
+ * \param tl: available length of temp scratchpad
+ * \param format: a printf style format specification
+ * \param ...: zero or more args for the format specification
+ *
+ * Creates a JWT in a single step, from the format string and args through to
+ * outputting a well-formed compact JWT representation in out.
+ *
+ * Returns 0 if all is well and *out_len is the amount of data in out, else
+ * nonzero if failed. Temp must be large enough to hold various intermediate
+ * representations.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_jwt_sign_compact(struct lws_context *ctx, struct lws_jwk *jwk,
+ const char *alg, char *out, size_t *out_len, char *temp,
+ int tl, const char *format, ...) LWS_FORMAT(8);
+
+struct lws_jwt_sign_info {
+ const char *alg;
+ /**< entry: signing alg name, like "RS256" */
+ const char *jose_hdr;
+ /**< entry: optional JOSE hdr; if present, alg field is ignored; instead the
+ * whole claim object has to be provided in this parameter */
+ size_t jose_hdr_len;
+ /**< entry: if jose_hdr is not NULL, JOSE header length without terminating '\0' */
+ char *out;
+ /**< exit: signed JWT in compact form*/
+ size_t *out_len;
+ /**< entry,exit: buffer size of out; actual size of JWT on exit */
+ char *temp;
+ /**< exit undefined content, used by the function as a temporary scratchpad; MUST
+ * be large enogh to store various intermediate representations */
+ int tl;
+ /**< entry: size of temp buffer */
+};
+
+/**
+ * lws_jwt_sign_compact() - generate a compact JWT using a key and JOSE header
+ *
+ * \param ctx: the lws_context
+ * \param jwk: the signing key
+ * \param info: info describing the JWT's content and output/temp buffers
+ * \param format: a printf style format specification of the claims object
+ * \param ...: zero or more args for the format specification
+ *
+ * Creates a JWT in a single step, from the format string and args through to
+ * outputting a well-formed compact JWT representation in out. The provided
+ * JOSE header's syntax is checked before it is added to the JWT.
+ *
+ * Returns 0 if all is well and *out_len is the amount of data in out, else
+ * nonzero if failed. Temp must be large enough to hold various intermediate
+ * representations.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_jwt_sign_via_info(struct lws_context *ctx, struct lws_jwk *jwk,
+ const struct lws_jwt_sign_info *info, const char *format, ...) LWS_FORMAT(4);
+
+/**
+ * lws_jwt_token_sanity() - check a validated jwt payload for sanity
+ *
+ * \param in: the JWT payload
+ * \param in_len: the length of the JWT payload
+ * \param iss: the expected issuer of the token
+ * \param aud: the expected audience of the token
+ * \param csrf_in: NULL, or the csrf token that came in on a URL
+ * \param sub: a buffer to hold the subject name in the JWT (eg, account name)
+ * \param sub_len: the max length of the sub buffer
+ * \param secs_left: set to the number of seconds of valid auth left if valid
+ *
+ * This performs some generic sanity tests on validated JWT payload...
+ *
+ * - the issuer is as expected
+ * - the audience is us
+ * - current time is OK for nbf ("not before") in the token
+ * - current time is OK for exp ("expiry") in the token
+ * - if csrf_in is not NULL, that the JWK has a csrf and it matches it
+ * - if sub is not NULL, that the JWK provides a subject (and copies it to sub)
+ *
+ * If the tests pass, *secs_left is set to the number of remaining seconds the
+ * auth is valid.
+ *
+ * Returns 0 if no inconsistency, else nonzero.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_jwt_token_sanity(const char *in, size_t in_len,
+ const char *iss, const char *aud, const char *csrf_in,
+ char *sub, size_t sub_len, unsigned long *exp_unix_time);
+
+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
+
+struct lws_jwt_sign_set_cookie {
+ struct lws_jwk *jwk;
+ /**< entry: required signing key */
+ const char *alg;
+ /**< entry: required signing alg, eg, "ES512" */
+ const char *iss;
+ /**< entry: issuer name to use */
+ const char *aud;
+ /**< entry: audience */
+ const char *cookie_name;
+ /**< entry: the name of the cookie */
+ char sub[33];
+ /**< sign-entry, validate-exit: subject */
+ const char *extra_json;
+ /**< sign-entry, validate-exit:
+ * optional "ext" JSON object contents for the JWT */
+ size_t extra_json_len;
+ /**< validate-exit:
+ * length of optional "ext" JSON object contents for the JWT */
+ const char *csrf_in;
+ /**< validate-entry:
+ * NULL, or an external CSRF token to check against what is in the JWT */
+ unsigned long expiry_unix_time;
+ /**< sign-entry: seconds the JWT and cookie may live,
+ * validate-exit: expiry unix time */
+};
+
+/**
+ * lws_jwt_sign_token_set_cookie() - creates sets a JWT in a wsi cookie
+ *
+ * \param wsi: the wsi to create the cookie header on
+ * \param i: structure describing what should be in the JWT
+ * \param p: wsi headers area
+ * \param end: end of wsi headers area
+ *
+ * Creates a JWT specified \p i, and attaches it to the outgoing headers on
+ * wsi. Returns 0 if successful.
+ *
+ * Best-practice security restrictions are applied to the cookie set action,
+ * including forcing httponly, and __Host- prefix. As required by __Host-, the
+ * cookie Path is set to /. __Host- is applied by the function, the cookie_name
+ * should just be "xyz" for "__Host-xyz".
+ *
+ * \p extra_json should just be the bare JSON, a { } is provided around it by
+ * the function if it's non-NULL. For example, "\"authorization\": 1".
+ *
+ * It's recommended the secs parameter is kept as small as consistent with one
+ * user session on the site if possible, eg, 10 minutes or 20 minutes. At the
+ * server, it can determine how much time is left in the auth and inform the
+ * client; if the JWT validity expires, the page should reload so the UI always
+ * reflects what's possible to do with the authorization state correctly. If
+ * the JWT expires, the user can log back in using credentials usually stored in
+ * the browser and auto-filled-in, so this is not very inconvenient.
+ *
+ * This is a helper on top of the other JOSE and JWT apis that somewhat crosses
+ * over between JWT and HTTP, since it knows about cookies. So it is only built
+ * if both LWS_WITH_JOSE and one of the http-related roles enabled.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_jwt_sign_token_set_http_cookie(struct lws *wsi,
+ const struct lws_jwt_sign_set_cookie *i,
+ uint8_t **p, uint8_t *end);
+LWS_VISIBLE LWS_EXTERN int
+lws_jwt_get_http_cookie_validate_jwt(struct lws *wsi,
+ struct lws_jwt_sign_set_cookie *i,
+ char *out, size_t *out_len);
+#endif
+
///@}
--- /dev/null
+/*
+ * Generic LED controller ops
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * This is like an abstract class for leds, a real implementation provides
+ * functions for the ops that use the underlying, eg, OS gpio arrangements.
+ */
+
+/* only b15 significant for GPIO */
+typedef uint16_t lws_led_intensity_t;
+typedef uint16_t lws_led_seq_phase_t;
+
+/* the normalized max intensity */
+#define LWS_LED_MAX_INTENSITY (0xffff)
+
+/* the normalized 360 degree phase count for intensity functions */
+#define LWS_LED_FUNC_PHASE 65536
+/* used when the sequence doesn't stop by itself and goes around forever */
+#define LWS_SEQ_LEDPHASE_TOTAL_ENDLESS (-1)
+
+#define LWS_LED_SEQUENCER_UPDATE_INTERVAL_MS 33
+
+struct lws_led_state; /* opaque */
+struct lws_pwm_ops; /* forward ref */
+
+typedef lws_led_intensity_t (*lws_led_lookup_t)(lws_led_seq_phase_t ph);
+
+typedef struct lws_led_sequence_def_t {
+ lws_led_lookup_t func;
+ lws_led_seq_phase_t ledphase_offset;
+ int ledphase_total; /* 65536= one cycle */
+ uint16_t ms;
+ uint8_t flags;
+} lws_led_sequence_def_t;
+
+enum {
+ LLSI_CURR,
+ LLSI_NEXT,
+ LLSI_TRANS
+};
+
+typedef struct lws_led_state_ch
+{
+ const lws_led_sequence_def_t *seq; /* NULL = inactive */
+ lws_led_seq_phase_t ph;
+ lws_led_seq_phase_t step;
+ int phase_budget;
+ lws_led_intensity_t last;
+ /**< at the end of the sequence we decouple the sequencer, but leave
+ * the last computed sample behind for further transitions to base off
+ */
+} lws_led_state_ch_t;
+
+typedef struct lws_led_state_chs
+{
+ lws_led_state_ch_t seqs[3];
+} lws_led_state_chs_t;
+
+/* this should always be first in the subclassed implementation types */
+
+typedef struct lws_led_ops {
+ void (*intensity)(const struct lws_led_ops *lo, const char *name,
+ lws_led_intensity_t inten);
+ /**< for BOOL led control like GPIO, only inten b15 is significant */
+ struct lws_led_state * (*create)(const struct lws_led_ops *led_ops);
+ void (*destroy)(struct lws_led_state *);
+} lws_led_ops_t;
+
+typedef struct lws_led_gpio_map {
+ const char *name;
+ _lws_plat_gpio_t gpio;
+ lws_led_lookup_t intensity_correction;
+ /**< May be NULL. If GPIO-based LED, ignored. If pwm_ops provided,
+ * NULL means use default CIE 100% correction function. If non-NULL,
+ * use the pointed-to correction function. This is useful to provide
+ * LED-specific intensity correction / scaling so different types of
+ * LED can "look the same". */
+ const struct lws_pwm_ops *pwm_ops;
+ /**< if NULL, gpio controls the led directly. If set to a pwm_ops,
+ * the led control is outsourced to the pwm controller. */
+ uint8_t active_level;
+} lws_led_gpio_map_t;
+
+typedef struct lws_led_gpio_controller {
+ const lws_led_ops_t led_ops;
+
+ const lws_gpio_ops_t *gpio_ops;
+ const lws_led_gpio_map_t *led_map;
+ uint8_t count_leds;
+} lws_led_gpio_controller_t;
+
+/* ops */
+
+LWS_VISIBLE LWS_EXTERN struct lws_led_state *
+lws_led_gpio_create(const lws_led_ops_t *led_ops);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_led_gpio_destroy(struct lws_led_state *lcs);
+
+/**
+ * lws_led_gpio_intensity() - set the static intensity of an led
+ *
+ * \param lo: the base class of the led controller
+ * \param index: which led in the controller set
+ * \param inten: 16-bit unsigned intensity
+ *
+ * For LEDs controlled by a BOOL like GPIO, only inten b15 is significant.
+ * For PWM type LED control, as many bits as the hardware can support from b15
+ * down are significant.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_led_gpio_intensity(const struct lws_led_ops *lo, const char *name,
+ lws_led_intensity_t inten);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_led_transition(struct lws_led_state *lcs, const char *name,
+ const lws_led_sequence_def_t *next,
+ const lws_led_sequence_def_t *trans);
+
+
+#define lws_led_gpio_ops \
+ { \
+ .create = lws_led_gpio_create, \
+ .destroy = lws_led_gpio_destroy, \
+ .intensity = lws_led_gpio_intensity, \
+ }
+
*
* LEJPCB_VAL_STR_START: We are starting to parse a string, no data yet
*
- * LEJPCB_VAL_STR_CHUNK: We parsed LEJP_STRING_CHUNK -1 bytes of string data in
- * ctx->buf, which is as much as we can buffer, so we are
- * spilling it. If all your strings are less than
- * LEJP_STRING_CHUNK - 1 bytes, you will never see this
- * callback.
+ * LEJPCB_VAL_STR_CHUNK: We filled the string buffer in the ctx, but it's not
+ * the end of the string. We produce this to spill the
+ * intermediate buffer to the user code, so we can handle
+ * huge JSON strings using only the small buffer in the
+ * ctx. If the whole JSON string fits in the ctx buffer,
+ * you won't get these callbacks.
*
* LEJPCB_VAL_STR_END: String parsing has completed, the last chunk of the
* string is in ctx->buf.
#define LEJP_MAX_DEPTH 12
#endif
#ifndef LEJP_MAX_INDEX_DEPTH
-#define LEJP_MAX_INDEX_DEPTH 5
+#define LEJP_MAX_INDEX_DEPTH 8
#endif
#ifndef LEJP_MAX_PATH
#define LEJP_MAX_PATH 128
uint8_t path_match_len;
uint8_t wildcount;
uint8_t pst_sp; /* parsing stack head */
+ uint8_t outer_array;
};
LWS_VISIBLE LWS_EXTERN void
* returns length written in p
*/
LWS_VISIBLE LWS_EXTERN int
-lwsl_timestamp(int level, char *p, int len);
+lwsl_timestamp(int level, char *p, size_t len);
#if defined(LWS_PLAT_OPTEE) && !defined(LWS_WITH_NETWORK)
#define _lws_log(aaa, ...) SMSG(__VA_ARGS__)
#define _LWS_LINIT ((1 << LLL_COUNT) - 1)
#endif
#else /* not _DEBUG */
+#if defined(LWS_WITH_NO_LOGS)
+#define _LWS_LINIT (LLL_ERR | LLL_USER)
+#else
#define _LWS_LINIT (LLL_ERR | LLL_USER | LLL_WARN | LLL_NOTICE)
+#endif
#endif /* _DEBUG */
/*
LWS_VISIBLE LWS_EXTERN int
lwsl_visible(int level);
+struct lws;
+
+LWS_VISIBLE LWS_EXTERN const char *
+lws_wsi_tag(struct lws *wsi);
+
///@}
lwsac_reference(struct lwsac *head);
/**
- * lwsac_reference() - increase the lwsac reference count
+ * lwsac_unreference() - decrease the lwsac reference count
*
* \param head: pointer to the lwsac list object
*
* cases
*/
LWS_VISIBLE LWS_EXTERN int
-lwsac_extend(struct lwsac *head, int amount);
+lwsac_extend(struct lwsac *head, size_t amount);
/* helpers to keep a file cached in memory */
--- /dev/null
+ /*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * Public apis related to metric collection and reporting
+ */
+
+/* lws_metrics public part */
+
+typedef uint64_t u_mt_t;
+
+enum {
+ LWSMTFL_REPORT_OUTLIERS = (1 << 0),
+ /**< track outliers and report them internally */
+ LWSMTFL_REPORT_OOB = (1 << 1),
+ /**< report events as they happen */
+ LWSMTFL_REPORT_INACTIVITY_AT_PERIODIC = (1 << 2),
+ /**< explicitly externally report no activity at periodic cb, by
+ * default no events in the period is just not reported */
+ LWSMTFL_REPORT_MEAN = (1 << 3),
+ /**< average/min/max is meaningful, else only sum is meaningful */
+ LWSMTFL_REPORT_ONLY_GO = (1 << 4),
+ /**< no-go pieces invalid */
+ LWSMTFL_REPORT_DUTY_WALLCLOCK_US = (1 << 5),
+ /**< aggregate compares to wallclock us for duty cycle */
+ LWSMTFL_REPORT_HIST = (1 << 6),
+ /**< our type is histogram (otherwise, sum / mean aggregation) */
+};
+
+/*
+ * lws_metrics_tag allows your object to accumulate OpenMetrics-style
+ * descriptive tags before accounting for it with a metrics object at the end.
+ *
+ * Tags should represent low entropy information that is likely to repeat
+ * identically, so, eg, http method name, not eg, latency in us which is
+ * unlikely to be seen the same twice.
+ *
+ * Tags are just a list of name=value pairs, used for qualifying the final
+ * metrics entry with decorations in additional dimensions. For example,
+ * rather than keep individual metrics on methods, scheme, mountpoint, result
+ * code, you can keep metrics on http transactions only, and qualify the
+ * transaction metrics entries with tags that can be queried on the metrics
+ * backend to get the finer-grained information.
+ *
+ * http_srv{code="404",mount="/",method="GET",scheme="http"} 3
+ *
+ * For OpenMetrics the tags are converted to a { list } and appended to the base
+ * metrics name before using with actual metrics objects, the same set of tags
+ * on different transactions resolve to the same qualification string.
+ */
+
+typedef struct lws_metrics_tag {
+ lws_dll2_t list;
+
+ const char *name; /* tag, intended to be in .rodata, not copied */
+ /* overallocated value */
+} lws_metrics_tag_t;
+
+LWS_EXTERN LWS_VISIBLE int
+lws_metrics_tag_add(lws_dll2_owner_t *owner, const char *name, const char *val);
+
+#if defined(LWS_WITH_SYS_METRICS)
+/*
+ * wsi-specific version that also appends the tag value to the lifecycle tag
+ * used for logging the wsi identity
+ */
+LWS_EXTERN LWS_VISIBLE int
+lws_metrics_tag_wsi_add(struct lws *wsi, const char *name, const char *val);
+#else
+#define lws_metrics_tag_wsi_add(_a, _b, _c)
+#endif
+
+#if defined(LWS_WITH_SECURE_STREAMS)
+/*
+ * ss-specific version that also appends the tag value to the lifecycle tag
+ * used for logging the ss identity
+ */
+#if defined(LWS_WITH_SYS_METRICS)
+LWS_EXTERN LWS_VISIBLE int
+lws_metrics_tag_ss_add(struct lws_ss_handle *ss, const char *name, const char *val);
+#else
+#define lws_metrics_tag_ss_add(_a, _b, _c)
+#endif
+#endif
+
+LWS_EXTERN LWS_VISIBLE void
+lws_metrics_tags_destroy(lws_dll2_owner_t *owner);
+
+LWS_EXTERN LWS_VISIBLE size_t
+lws_metrics_tags_serialize(lws_dll2_owner_t *owner, char *buf, size_t len);
+
+LWS_EXTERN LWS_VISIBLE const char *
+lws_metrics_tag_get(lws_dll2_owner_t *owner, const char *name);
+
+/* histogram bucket */
+
+typedef struct lws_metric_bucket {
+ struct lws_metric_bucket *next;
+ uint64_t count;
+
+ /* name + NUL is overallocated */
+} lws_metric_bucket_t;
+
+/* get overallocated name of bucket from bucket pointer */
+#define lws_metric_bucket_name_len(_b) (*((uint8_t *)&(_b)[1]))
+#define lws_metric_bucket_name(_b) (((const char *)&(_b)[1]) + 1)
+
+/*
+ * These represent persistent local event measurements. They may aggregate
+ * a large number of events inbetween external dumping of summaries of the
+ * period covered, in two different ways
+ *
+ * 1) aggregation by sum or mean, to absorb multiple scalar readings
+ *
+ * - go / no-go ratio counting
+ * - mean averaging for, eg, latencies
+ * - min / max for averaged values
+ * - period the stats covers
+ *
+ * 2) aggregation by histogram, to absorb a range of outcomes that may occur
+ * multiple times
+ *
+ * - add named buckets to histogram
+ * - bucket has a 64-bit count
+ * - bumping a bucket just increments the count if already exists, else adds
+ * a new one with count set to 1
+ *
+ * The same type with a union covers both cases.
+ *
+ * The lws_system ops api that hooks lws_metrics up to a metrics backend is
+ * given a pointer to these according to the related policy, eg, hourly, or
+ * every event passed straight through.
+ */
+
+typedef struct lws_metric_pub {
+ const char *name;
+ /**< eg, "n.cn.dns", "vh.myendpoint" */
+ void *backend_opaque;
+ /**< ignored by lws, backend handler completely owns it */
+
+ lws_usec_t us_first;
+ /**< us time metric started collecting, reset to us_dumped at dump */
+ lws_usec_t us_last;
+ /**< 0, or us time last event, reset to 0 at last dump */
+ lws_usec_t us_dumped;
+ /**< 0 if never, else us time of last dump to external api */
+
+ /* scope of data in .u is "since last dump" --> */
+
+ union {
+ /* aggregation, by sum or mean */
+
+ struct {
+ u_mt_t sum[2];
+ /**< go, no-go summed for mean or plan sum */
+ u_mt_t min;
+ /**< smallest individual measurement */
+ u_mt_t max;
+ /**< largest individual measurement */
+
+ uint32_t count[2];
+ /**< go, no-go count of measurements in sum */
+ } agg;
+
+ /* histogram with dynamic named buckets */
+
+ struct {
+ lws_metric_bucket_t *head;
+ /**< first bucket in our bucket list */
+
+ uint64_t total_count;
+ /**< total count in all of our buckets */
+ uint32_t list_size;
+ /**< number of buckets in our bucket list */
+ } hist;
+ } u;
+
+ uint8_t flags;
+
+} lws_metric_pub_t;
+
+LWS_EXTERN LWS_VISIBLE void
+lws_metrics_hist_bump_priv_tagged(lws_metric_pub_t *mt, lws_dll2_owner_t *tow,
+ lws_dll2_owner_t *tow2);
+
+
+/*
+ * Calipers are a helper struct for implementing "hanging latency" detection,
+ * where setting the start time and finding the end time may happen in more than
+ * one place.
+ *
+ * There are convenience wrappers to eliminate caliper definitions and code
+ * cleanly if WITH_SYS_METRICS is disabled for the build.
+ */
+
+struct lws_metric;
+
+typedef struct lws_metric_caliper {
+ struct lws_dll2_owner mtags_owner; /**< collect tags here during
+ * caliper lifetime */
+ struct lws_metric *mt; /**< NULL == inactive */
+ lws_usec_t us_start;
+} lws_metric_caliper_t;
+
+#if defined(LWS_WITH_SYS_METRICS)
+#define lws_metrics_caliper_compose(_name) \
+ lws_metric_caliper_t _name;
+#define lws_metrics_caliper_bind(_name, _mt) \
+ { if (_name.mt) { \
+ lwsl_err("caliper: overwrite %s\n", \
+ lws_metrics_priv_to_pub(_name.mt)->name); \
+ assert(0); } \
+ _name.mt = _mt; _name.us_start = lws_now_usecs(); }
+#define lws_metrics_caliper_declare(_name, _mt) \
+ lws_metric_caliper_t _name = { .mt = _mt, .us_start = lws_now_usecs() }
+#define lws_metrics_caliper_report(_name, _go_nogo) \
+ { if (_name.us_start) { lws_metric_event(_name.mt, _go_nogo, \
+ (u_mt_t)(lws_now_usecs() - \
+ _name.us_start)); \
+ } lws_metrics_caliper_done(_name); }
+#define lws_metrics_caliper_report_hist(_name, pwsi) if (_name.mt) { \
+ lws_metrics_hist_bump_priv_tagged(lws_metrics_priv_to_pub(_name.mt), \
+ &_name.mtags_owner, \
+ pwsi ? &((pwsi)->cal_conn.mtags_owner) : NULL); \
+ lws_metrics_caliper_done(_name); }
+
+#define lws_metrics_caliper_cancel(_name) { lws_metrics_caliper_done(_name); }
+#define lws_metrics_hist_bump(_mt, _name) \
+ lws_metrics_hist_bump_(_mt, _name)
+#define lws_metrics_hist_bump_priv(_mt, _name) \
+ lws_metrics_hist_bump_(lws_metrics_priv_to_pub(_mt), _name)
+#define lws_metrics_caliper_done(_name) { \
+ _name.us_start = 0; _name.mt = NULL; \
+ lws_metrics_tags_destroy(&_name.mtags_owner); }
+#else
+#define lws_metrics_caliper_compose(_name)
+#define lws_metrics_caliper_bind(_name, _mt)
+#define lws_metrics_caliper_declare(_name, _mp)
+#define lws_metrics_caliper_report(_name, _go_nogo)
+#define lws_metrics_caliper_report_hist(_name, pwsiconn)
+#define lws_metrics_caliper_cancel(_name)
+#define lws_metrics_hist_bump(_mt, _name)
+#define lws_metrics_hist_bump_priv(_mt, _name)
+#define lws_metrics_caliper_done(_name)
+#endif
+
+/**
+ * lws_metrics_format() - helper to format a metrics object for logging
+ *
+ * \param pub: public part of metrics object
+ * \param buf: output buffer to place string in
+ * \param len: available length of \p buf
+ *
+ * Helper for describing the state of a metrics object as a human-readable
+ * string, accounting for how its flags indicate what it contains. This is not
+ * how you would report metrics, but during development it can be useful to
+ * log them inbetween possibily long report intervals.
+ *
+ * It uses the metric's flags to adapt the format shown appropriately, eg,
+ * as a histogram if LWSMTFL_REPORT_HIST etc
+ */
+LWS_EXTERN LWS_VISIBLE int
+lws_metrics_format(lws_metric_pub_t *pub, lws_metric_bucket_t **sub,
+ char *buf, size_t len);
+
+/**
+ * lws_metrics_hist_bump() - add or increment histogram bucket
+ *
+ * \param pub: public part of metrics object
+ * \param name: bucket name to increment
+ *
+ * Either increment the count of an existing bucket of the right name in the
+ * metrics object, or add a new bucket of the given name and set its count to 1.
+ *
+ * The metrics object must have been created with flag LWSMTFL_REPORT_HIST
+ *
+ * Normally, you will actually use the preprocessor wrapper
+ * lws_metrics_hist_bump() defined above, since this automatically takes care of
+ * removing itself from the build if WITH_SYS_METRICS is not defined, without
+ * needing any preprocessor conditionals.
+ */
+LWS_EXTERN LWS_VISIBLE int
+lws_metrics_hist_bump_(lws_metric_pub_t *pub, const char *name);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_metrics_foreach(struct lws_context *ctx, void *user,
+ int (*cb)(lws_metric_pub_t *pub, void *user));
+
+LWS_VISIBLE LWS_EXTERN int
+lws_metrics_hist_bump_describe_wsi(struct lws *wsi, lws_metric_pub_t *pub,
+ const char *name);
+
+enum {
+ LMT_NORMAL = 0, /* related to successful events */
+ LMT_OUTLIER, /* related to successful events outside of bounds */
+
+ LMT_FAIL, /* related to failed events */
+
+ LMT_COUNT,
+};
+
+typedef enum lws_metric_rpt {
+ LMR_PERIODIC = 0, /* we are reporting on a schedule */
+ LMR_OUTLIER, /* we are reporting the last outlier */
+} lws_metric_rpt_kind_t;
+
+#define METRES_GO 0
+#define METRES_NOGO 1
+
+
/*
* libwebsockets - small server side websockets and web server implementation
*
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
#endif
#endif
+#if defined(__OpenBSD__)
+#include <sys/siginfo.h>
+#endif
+
/** \defgroup misc Miscellaneous APIs
* ##Miscellaneous APIs
*
size_t len);
/**
+ * lws_buflist_linear_use(): copy and consume from buflist head
+ *
+ * \param head: list head
+ * \param buf: buffer to copy linearly into
+ * \param len: length of buffer available
+ *
+ * Copies a possibly fragmented buflist from the head into the linear output
+ * buffer \p buf for up to length \p len, and consumes the buflist content that
+ * was copied out.
+ *
+ * Since it was consumed, calling again will resume copying out and consuming
+ * from as far as it got the first time.
+ *
+ * Returns the number of bytes written into \p buf.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_buflist_linear_use(struct lws_buflist **head, uint8_t *buf, size_t len);
+
+/**
+ * lws_buflist_fragment_use(): copy and consume <= 1 frag from buflist head
+ *
+ * \param head: list head
+ * \param buf: buffer to copy linearly into
+ * \param len: length of buffer available
+ * \param frag_first: pointer to char written on exit to if this is start of frag
+ * \param frag_fin: pointer to char written on exit to if this is end of frag
+ *
+ * Copies all or part of the fragment at the start of a buflist from the head
+ * into the output buffer \p buf for up to length \p len, and consumes the
+ * buflist content that was copied out.
+ *
+ * Since it was consumed, calling again will resume copying out and consuming
+ * from as far as it got the first time.
+ *
+ * Returns the number of bytes written into \p buf.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_buflist_fragment_use(struct lws_buflist **head, uint8_t *buf,
+ size_t len, char *frag_first, char *frag_fin);
+
+/**
* lws_buflist_destroy_all_segments(): free all segments on the list
*
* \param head: list head
#define lws_ptr_diff(head, tail) \
((int)((char *)(head) - (char *)(tail)))
+#define lws_ptr_diff_size_t(head, tail) \
+ ((size_t)(ssize_t)((char *)(head) - (char *)(tail)))
+
/**
* lws_snprintf(): snprintf that truncates the returned length too
*
(size_t)(size1 + 1) : (size_t)(destsize))
/**
+ * lws_nstrstr(): like strstr for length-based strings without terminating NUL
+ *
+ * \param buf: the string to search
+ * \param len: the length of the string to search
+ * \param name: the substring to search for
+ * \param nl: the length of name
+ *
+ * Returns NULL if \p name is not present in \p buf. Otherwise returns the
+ * address of the first instance of \p name in \p buf.
+ *
+ * Neither buf nor name need to be NUL-terminated.
+ */
+LWS_VISIBLE LWS_EXTERN const char *
+lws_nstrstr(const char *buf, size_t len, const char *name, size_t nl);
+
+/**
+ * lws_json_simple_find(): dumb JSON string parser
+ *
+ * \param buf: the JSON to search
+ * \param len: the length of the JSON to search
+ * \param name: the name field to search the JSON for, eg, "\"myname\":"
+ * \param alen: set to the length of the argument part if non-NULL return
+ *
+ * Either returns NULL if \p name is not present in buf, or returns a pointer
+ * to the argument body of the first instance of \p name, and sets *alen to the
+ * length of the argument body.
+ *
+ * This can cheaply handle fishing out, eg, myarg from {"myname": "myarg"} by
+ * searching for "\"myname\":". It will return a pointer to myarg and set *alen
+ * to 5. It equally handles args like "myname": true, or "myname":false, and
+ * null or numbers are all returned as delimited strings.
+ *
+ * Anything more complicated like the value is a subobject or array, you should
+ * parse it using a full parser like lejp. This is suitable is the JSON is
+ * and will remain short and simple, and contains well-known names amongst other
+ * extensible JSON members.
+ */
+LWS_VISIBLE LWS_EXTERN const char *
+lws_json_simple_find(const char *buf, size_t len, const char *name, size_t *alen);
+
+/**
+ * lws_json_simple_strcmp(): dumb JSON string comparison
+ *
+ * \param buf: the JSON to search
+ * \param len: the length of the JSON to search
+ * \param name: the name field to search the JSON for, eg, "\"myname\":"
+ * \param comp: return a strcmp of this and the discovered argument
+ *
+ * Helper that combines lws_json_simple_find() with strcmp() if it was found.
+ * If the \p name was not found, returns -1. Otherwise returns a strcmp()
+ * between what was found and \p comp, ie, return 0 if they match or something
+ * else if they don't.
+ *
+ * If the JSON is relatively simple and you want to target constrained
+ * devices, this can be a good choice. If the JSON may be complex, you
+ * should use a full JSON parser.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_json_simple_strcmp(const char *buf, size_t len, const char *name, const char *comp);
+
+
+/**
* lws_hex_to_byte_array(): convert hex string like 0123456789ab into byte data
*
* \param h: incoming NUL-terminated hex string
LWS_VISIBLE LWS_EXTERN int
lws_hex_to_byte_array(const char *h, uint8_t *dest, int max);
+/**
+ * lws_hex_from_byte_array(): render byte array as hex char string
+ *
+ * \param src: incoming binary source array
+ * \param slen: length of src in bytes
+ * \param dest: array to fill with hex chars representing src
+ * \param len: max extent of dest
+ *
+ * This converts binary data of length slen at src, into a hex string at dest
+ * of maximum length len. Even if truncated, the result will be NUL-terminated.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_hex_from_byte_array(const uint8_t *src, size_t slen, char *dest, size_t len);
+
+/**
+ * lws_hex_random(): generate len - 1 or - 2 characters of random ascii hex
+ *
+ * \param context: the lws_context used to get the random
+ * \param dest: destination for hex ascii chars
+ * \param len: the number of bytes the buffer dest points to can hold
+ *
+ * This creates random ascii-hex strings up to a given length, with a
+ * terminating NUL.
+ *
+ * There will not be any characters produced that are not 0-9, a-f, so it's
+ * safe to go straight into, eg, JSON.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_hex_random(struct lws_context *context, char *dest, size_t len);
+
/*
* lws_timingsafe_bcmp(): constant time memcmp
*
lws_wsi_user(struct lws *wsi);
/**
+ * lws_wsi_tsi() - get the service thread index the wsi is bound to
+ * \param wsi: lws connection
+ *
+ * Only useful is LWS_MAX_SMP > 1
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_wsi_tsi(struct lws *wsi);
+
+/**
* lws_set_wsi_user() - set the user data associated with the client connection
* \param wsi: lws connection
* \param user: user data
* and subdir creation / permissions down /var/cache dynamically.
*/
LWS_VISIBLE LWS_EXTERN void
-lws_get_effective_uid_gid(struct lws_context *context, int *uid, int *gid);
+lws_get_effective_uid_gid(struct lws_context *context, uid_t *uid, gid_t *gid);
/**
* lws_get_udp() - get wsi's udp struct
*/
LWS_VISIBLE LWS_EXTERN int
lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb);
+
+/**
+ * lws_dir_rm_rf_cb() - callback for lws_dir that performs recursive rm -rf
+ *
+ * \param dirpath: directory we are at in lws_dir
+ * \param user: ignored
+ * \param lde: lws_dir info on the file or directory we are at
+ *
+ * This is a readymade rm -rf callback for use with lws_dir. It recursively
+ * removes everything below the starting dir and then the starting dir itself.
+ * Works on linux, OSX and Windows at least.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_dir_rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde);
+
+/*
+ * We pass every file in the base dir through a filter, and call back on the
+ * ones that match. Directories are ignored.
+ *
+ * The original path filter string may look like, eg, "sai-*.deb" or "*.txt"
+ */
+
+typedef int (*lws_dir_glob_cb_t)(void *data, const char *path);
+
+typedef struct lws_dir_glob {
+ const char *filter;
+ lws_dir_glob_cb_t cb;
+ void *user;
+} lws_dir_glob_t;
+
+/**
+ * lws_dir_glob_cb() - callback for lws_dir that performs filename globbing
+ *
+ * \param dirpath: directory we are at in lws_dir
+ * \param user: pointer to your prepared lws_dir_glob_cb_t
+ * \param lde: lws_dir info on the file or directory we are at
+ *
+ * \p user is prepared with an `lws_dir_glob_t` containing a callback for paths
+ * that pass the filtering, a user pointer to pass to that callback, and a
+ * glob string like "*.txt". It may not contain directories, the lws_dir musr
+ * be started at the correct dir.
+ *
+ * Only the base path passed to lws_dir is scanned, it does not look in subdirs.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_dir_glob_cb(const char *dirpath, void *user, struct lws_dir_entry *lde);
+
#endif
/**
uint64_t factor;
} lws_humanize_unit_t;
-LWS_VISIBLE LWS_EXTERN const lws_humanize_unit_t humanize_schema_si[7];
-LWS_VISIBLE LWS_EXTERN const lws_humanize_unit_t humanize_schema_si_bytes[7];
-LWS_VISIBLE LWS_EXTERN const lws_humanize_unit_t humanize_schema_us[8];
+LWS_VISIBLE extern const lws_humanize_unit_t humanize_schema_si[7];
+LWS_VISIBLE extern const lws_humanize_unit_t humanize_schema_si_bytes[7];
+LWS_VISIBLE extern const lws_humanize_unit_t humanize_schema_us[8];
/**
* lws_humanize() - Convert possibly large number to human-readable uints
*/
LWS_VISIBLE LWS_EXTERN int
-lws_humanize(char *buf, int len, uint64_t value,
+lws_humanize(char *buf, size_t len, uint64_t value,
const lws_humanize_unit_t *schema);
LWS_VISIBLE LWS_EXTERN void
/* opaque internal struct */
struct lws_spawn_piped;
+#if defined(WIN32)
+struct _lws_siginfo_t {
+ int retcode;
+};
+typedef struct _lws_siginfo_t siginfo_t;
+#endif
+
typedef void (*lsp_cb_t)(void *opaque, lws_usec_t *accounting, siginfo_t *si,
int we_killed_him);
struct lws *opt_parent;
const char * const *exec_array;
- char **env_array;
+ const char **env_array;
const char *protocol_name;
const char *chroot_path;
const char *wd;
* lws_spawn_stdwsi_closed() - inform the spawn one of its stdxxx pipes closed
*
* \p lsp: the spawn object
+ * \p wsi: the wsi that is closing
*
* When you notice one of the spawn stdxxx pipes closed, inform the spawn
* instance using this api. When it sees all three have closed, it will
* has closed.
*/
LWS_VISIBLE LWS_EXTERN void
-lws_spawn_stdwsi_closed(struct lws_spawn_piped *lsp);
+lws_spawn_stdwsi_closed(struct lws_spawn_piped *lsp, struct lws *wsi);
/**
* lws_spawn_get_stdfd() - return std channel index for stdwsi
--- /dev/null
+/*
+ * libwebsockets - protocol - mqtt
+ *
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * included from libwebsockets.h
+ */
+
+#ifndef _LWS_MQTT_H
+#define _LWS_MQTT_H 1
+
+struct _lws_mqtt_related;
+typedef struct _lws_mqtt_related lws_mqtt_related_t;
+struct lws_mqtt_str_st;
+typedef struct lws_mqtt_str_st lws_mqtt_str_t;
+
+#define MQTT_VER_3_1_1 4
+
+#define LWS_MQTT_FINAL_PART 1
+
+#define LWS_MQTT_MAX_AWSIOT_TOPICLEN 256
+#define LWS_MQTT_MAX_TOPICLEN 65535
+#define LWS_MQTT_MAX_CIDLEN 128
+#define LWS_MQTT_RANDOM_CIDLEN 23 /* 3.1.3.1-5: Server MUST... between
+ 1 and 23 chars... */
+
+typedef enum {
+ QOS0,
+ QOS1,
+ QOS2, /* not supported */
+ RESERVED_QOS_LEVEL,
+ FAILURE_QOS_LEVEL = 0x80
+} lws_mqtt_qos_levels_t;
+
+typedef union {
+ struct {
+ uint8_t retain:1;
+ uint8_t qos:2;
+ uint8_t dup:1;
+ uint8_t ctrl_pkt_type:4;
+ } flags;
+ uint8_t bits;
+} lws_mqtt_fixed_hdr_t;
+
+/*
+ * MQTT connection parameters, passed into struct
+ * lws_client_connect_info to establish a connection using
+ * lws_client_connect_via_info().
+*/
+typedef struct lws_mqtt_client_connect_param_s {
+ const char *client_id; /* Client ID */
+ uint16_t keep_alive; /* MQTT keep alive
+ interval in
+ seconds */
+ uint8_t clean_start; /* MQTT clean
+ session */
+ struct {
+ const char *topic;
+ const char *message;
+ lws_mqtt_qos_levels_t qos;
+ uint8_t retain;
+ } will_param; /* MQTT LWT
+ parameters */
+ const char *username;
+ const char *password;
+ uint8_t aws_iot;
+} lws_mqtt_client_connect_param_t;
+
+/*
+ * MQTT publish parameters
+*/
+typedef struct lws_mqtt_publish_param_s {
+ char *topic; /* Topic Name */
+ uint16_t topic_len;
+ const void *payload; /* Publish Payload */
+ uint32_t payload_len; /* Size of the
+ complete payload */
+ uint32_t payload_pos; /* where we are in payload */
+ lws_mqtt_qos_levels_t qos;
+
+ /*--v-Following will be used by LWS-v--*/
+ uint16_t packet_id; /* Packet ID for QoS >
+ 0 */
+ uint8_t dup:1; /* Retried PUBLISH,
+ for QoS > 0 */
+} lws_mqtt_publish_param_t;
+
+typedef struct topic_elem {
+ const char *name; /* Topic Name */
+ lws_mqtt_qos_levels_t qos; /* Requested QoS */
+
+ /*--v-Following will be used by LWS-v--*/
+ uint8_t acked;
+} lws_mqtt_topic_elem_t;
+
+/*
+ * MQTT publish parameters
+*/
+typedef struct lws_mqtt_subscribe_param_s {
+ uint32_t num_topics; /* Number of topics */
+ lws_mqtt_topic_elem_t *topic; /* Array of topic elements */
+
+ /*--v-Following will be used by LWS-v--*/
+ uint16_t packet_id;
+} lws_mqtt_subscribe_param_t;
+
+typedef enum {
+ LMQCP_RESERVED,
+ LMQCP_CTOS_CONNECT, /* Connection request */
+ LMQCP_STOC_CONNACK, /* Connection acknowledgment */
+ LMQCP_PUBLISH, /* Publish Message */
+ LMQCP_PUBACK, /* QoS 1: Publish acknowledgment */
+ LMQCP_PUBREC, /* QoS 2.1: Publish received */
+ LMQCP_PUBREL, /* QoS 2.2: Publish release */
+ LMQCP_PUBCOMP, /* QoS 2.3: Publish complete */
+ LMQCP_CTOS_SUBSCRIBE, /* Subscribe request */
+ LMQCP_STOC_SUBACK, /* Subscribe acknowledgment */
+ LMQCP_CTOS_UNSUBSCRIBE, /* Unsubscribe request */
+ LMQCP_STOC_UNSUBACK, /* Unsubscribe acknowledgment */
+ LMQCP_CTOS_PINGREQ, /* PING request */
+ LMQCP_STOC_PINGRESP, /* PONG response */
+ LMQCP_DISCONNECT, /* Disconnect notification */
+ LMQCP_AUTH /* Authentication exchange */
+} lws_mqtt_control_packet_t;
+
+/* flags from byte 8 of C_TO_S CONNECT */
+typedef enum {
+ LMQCFT_USERNAME = (1 << 7),
+ LMQCFT_PASSWORD = (1 << 6),
+ LMQCFT_WILL_RETAIN = (1 << 5),
+ LMQCFT_WILL_QOS = (1 << 3),
+ LMQCFT_WILL_FLAG = (1 << 2),
+ LMQCFT_CLEAN_START = (1 << 1),
+ LMQCFT_RESERVED = (1 << 0),
+
+ LMQCFT_WILL_QOS_MASK = (3 << 3),
+} lws_mqtt_connect_flags_t;
+
+/* flags for S_TO_C CONNACK */
+typedef enum {
+ LMQCFT_SESSION_PRESENT = (1 << 0),
+} lws_mqtt_connack_flags_t;
+
+typedef enum {
+ LMQCP_REASON_SUCCESS = 0x00,
+ LMQCP_REASON_NORMAL_DISCONNECTION = 0x00,
+ LMQCP_REASON_GRANTED_QOS0 = 0x00,
+ LMQCP_REASON_GRANTED_QOS1 = 0x01,
+ LMQCP_REASON_GRANTED_QOS2 = 0x02,
+ LMQCP_REASON_DISCONNECT_WILL = 0x04,
+ LMQCP_REASON_NO_MATCHING_SUBSCRIBER = 0x10,
+ LMQCP_REASON_NO_SUBSCRIPTION_EXISTED = 0x11,
+ LMQCP_REASON_CONTINUE_AUTHENTICATION = 0x18,
+ LMQCP_REASON_RE_AUTHENTICATE = 0x19,
+
+ LMQCP_REASON_UNSPECIFIED_ERROR = 0x80,
+ LMQCP_REASON_MALFORMED_PACKET = 0x81,
+ LMQCP_REASON_PROTOCOL_ERROR = 0x82,
+ LMQCP_REASON_IMPLEMENTATION_SPECIFIC_ERROR = 0x83,
+
+ /* Begin - Error codes for CONNACK */
+ LMQCP_REASON_UNSUPPORTED_PROTOCOL = 0x84,
+ LMQCP_REASON_CLIENT_ID_INVALID = 0x85,
+ LMQCP_REASON_BAD_CREDENTIALS = 0x86,
+ LMQCP_REASON_NOT_AUTHORIZED = 0x87,
+ /* End - Error codes for CONNACK */
+
+ LMQCP_REASON_SERVER_UNAVAILABLE = 0x88,
+ LMQCP_REASON_SERVER_BUSY = 0x89,
+ LMQCP_REASON_BANNED = 0x8a,
+ LMQCP_REASON_SERVER_SHUTTING_DOWN = 0x8b,
+ LMQCP_REASON_BAD_AUTHENTICATION_METHOD = 0x8c,
+ LMQCP_REASON_KEEPALIVE_TIMEOUT = 0x8d,
+ LMQCP_REASON_SESSION_TAKEN_OVER = 0x8e,
+ LMQCP_REASON_TOPIC_FILTER_INVALID = 0x8f,
+ LMQCP_REASON_TOPIC_NAME_INVALID = 0x90,
+ LMQCP_REASON_PACKET_ID_IN_USE = 0x91,
+ LMQCP_REASON_PACKET_ID_NOT_FOUND = 0x92,
+ LMQCP_REASON_MAX_RX_EXCEEDED = 0x93,
+ LMQCP_REASON_TOPIC_ALIAS_INVALID = 0x94,
+ LMQCP_REASON_PACKET_TOO_LARGE = 0x95,
+ LMQCP_REASON_RATELIMIT = 0x96,
+ LMQCP_REASON_QUOTA_EXCEEDED = 0x97,
+ LMQCP_REASON_ADMINISTRATIVE_ACTION = 0x98,
+ LMQCP_REASON_PAYLOAD_FORMAT_INVALID = 0x99,
+ LMQCP_REASON_RETAIN_NOT_SUPPORTED = 0x9a,
+ LMQCP_REASON_QOS_NOT_SUPPORTED = 0x9b,
+ LMQCP_REASON_USE_ANOTHER_SERVER = 0x9c,
+ LMQCP_REASON_SERVER_MOVED = 0x9d,
+ LMQCP_REASON_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 0x9e,
+ LMQCP_REASON_CONNECTION_RATE_EXCEEDED = 0x9f,
+ LMQCP_REASON_MAXIMUM_CONNECT_TIME = 0xa0,
+ LMQCP_REASON_SUBSCRIPTION_IDS_NOT_SUPPORTED = 0xa1,
+ LMQCP_REASON_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 0xa2,
+} lws_mqtt_reason_t;
+
+typedef enum {
+ LMQPROP_INVALID,
+ LMQPROP_PAYLOAD_FORMAT_INDICATOR = 0x01,
+ LMQPROP_MESSAGE_EXPIRY_INTERVAL = 0x02,
+ LMQPROP_CONTENT_TYPE = 0x03,
+ LMQPROP_RESPONSE_TOPIC = 0x08,
+ LMQPROP_CORRELATION_DATA = 0x09,
+ LMQPROP_SUBSCRIPTION_IDENTIFIER = 0x0b,
+ LMQPROP_SESSION_EXPIRY_INTERVAL = 0x11,
+ LMQPROP_ASSIGNED_CLIENT_IDENTIFIER = 0x12,
+ LMQPROP_SERVER_KEEP_ALIVE = 0x13,
+ LMQPROP_AUTHENTICATION_METHOD = 0x15,
+ LMQPROP_AUTHENTICATION_DATA = 0x16,
+ LMQPROP_REQUEST_PROBLEM_INFORMATION = 0x17,
+ LMQPROP_WILL_DELAY_INTERVAL = 0x18,
+ LMQPROP_REQUEST_RESPONSE_INFORMATION = 0x19,
+ LMQPROP_RESPONSE_INFORMATION = 0x1a,
+ LMQPROP_SERVER_REFERENCE = 0x1c,
+ LMQPROP_REASON_STRING = 0x1f,
+ LMQPROP_RECEIVE_MAXIMUM = 0x21,
+ LMQPROP_TOPIC_ALIAS_MAXIMUM = 0x22,
+ LMQPROP_TOPIC_ALIAS = 0x23,
+ LMQPROP_MAXIMUM_QOS = 0x24,
+ LMQPROP_RETAIN_AVAILABLE = 0x25,
+ LMQPROP_USER_PROPERTY = 0x26,
+ LMQPROP_MAXIMUM_PACKET_SIZE = 0x27,
+ LMQPROP_WILDCARD_SUBSCRIPTION_AVAIL = 0x28,
+ LMQPROP_SUBSCRIPTION_IDENTIFIER_AVAIL = 0x29,
+ LMQPROP_SHARED_SUBSCRIPTION_AVAIL = 0x2a
+} lws_mqtt_property;
+
+int
+lws_read_mqtt(struct lws *wsi, unsigned char *buf, lws_filepos_t len);
+
+/* returns 0 if bd1 and bd2 are "the same", that includes empty, else nonzero */
+LWS_VISIBLE LWS_EXTERN int
+lws_mqtt_bindata_cmp(const lws_mqtt_str_t *bd1, const lws_mqtt_str_t *bd2);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_mqtt_str_init(lws_mqtt_str_t *s, uint8_t *buf, uint16_t lim, char nf);
+
+LWS_VISIBLE LWS_EXTERN lws_mqtt_str_t *
+lws_mqtt_str_create(uint16_t lim);
+
+LWS_VISIBLE LWS_EXTERN lws_mqtt_str_t *
+lws_mqtt_str_create_init(uint8_t *buf, uint16_t len, uint16_t lim);
+
+LWS_VISIBLE LWS_EXTERN lws_mqtt_str_t *
+lws_mqtt_str_create_cstr_dup(const char *buf, uint16_t lim);
+
+LWS_VISIBLE LWS_EXTERN uint8_t *
+lws_mqtt_str_next(lws_mqtt_str_t *s, uint16_t *budget);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_mqtt_str_advance(lws_mqtt_str_t *s, int n);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_mqtt_str_free(lws_mqtt_str_t **s);
+
+
+/**
+ * lws_mqtt_client_send_publish() - lws_write a publish packet
+ *
+ * \param wsi: the mqtt child wsi
+ * \param pub: additional information on what we're publishing
+ * \param buf: payload to send
+ * \param len: length of data in buf
+ * \param final: flag indicating this is the last part
+ *
+ * Issues part of, or the whole of, a PUBLISH frame. The first part of the
+ * frame contains the header, and uses the .qos and .payload_len parts of \p pub
+ * since MQTT requires the frame to specify the PUBLISH message length at the
+ * start. The \p len paramter may be less than \p pub.payload_len, in which
+ * case subsequent calls with more payload are needed to complete the frame.
+ *
+ * Although the connection is stuck waiting for the remainder, in that it can't
+ * issue any other frames until the current one is completed, lws returns to the
+ * event loop normally and can continue the calls with additional payload even
+ * for huge frames as the data becomes available, consistent with timeout needs
+ * and latency to start any new frame (even, eg, related to ping / pong).
+ *
+ * If you're sending large frames, the OS will typically not allow the data to
+ * be sent all at once to kernel side. So you should ideally cut the payload
+ * up into 1 or 2- mtu sized chunks and send that.
+ *
+ * Final should be set when you're calling with the last part of the payload.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_mqtt_client_send_publish(struct lws *wsi, lws_mqtt_publish_param_t *pub,
+ const void *buf, uint32_t len, int final);
+
+/**
+ * lws_mqtt_client_send_subcribe() - lws_write a subscribe packet
+ *
+ * \param wsi: the mqtt child wsi
+ * \param sub: which topic(s) we want to subscribe to
+ *
+ * For topics other child streams have not already subscribed to, send a packet
+ * to the server asking to subscribe to them. If all topics listed are already
+ * subscribed to be the shared network connection, just trigger the
+ * LWS_CALLBACK_MQTT_SUBSCRIBED callback as if a SUBACK had come.
+ *
+ * \p sub doesn't need to exist after the return from this function.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_mqtt_client_send_subcribe(struct lws *wsi, lws_mqtt_subscribe_param_t *sub);
+
+/**
+ * lws_mqtt_client_send_unsubcribe() - lws_write a unsubscribe packet
+ *
+ * \param wsi: the mqtt child wsi
+ * \param sub: which topic(s) we want to unsubscribe from
+ *
+ * For topics other child streams are not subscribed to, send a packet
+ * to the server asking to unsubscribe from them. If all topics
+ * listed are already subscribed by other child streams on the shared
+ * network connection, just trigger the LWS_CALLBACK_MQTT_UNSUBSCRIBED
+ * callback as if a UNSUBACK had come.
+ *
+ * \p unsub doesn't need to exist after the return from this function.
+ */
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_mqtt_client_send_unsubcribe(struct lws *wsi,
+ const lws_mqtt_subscribe_param_t *unsub);
+
+#endif /* _LWS_MQTT_H */
--- /dev/null
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ */
+
+#define LWS_WIFI_MAX_SCAN_TRACK 16
+#define LWS_ETH_ALEN 6
+
+typedef uint8_t lws_wifi_ch_t;
+typedef int8_t lws_wifi_rssi_t;
+struct lws_netdev_instance;
+
+typedef enum {
+ LWSNDTYP_UNKNOWN,
+ LWSNDTYP_WIFI,
+ LWSNDTYP_ETH,
+} lws_netdev_type_t;
+
+/*
+ * Base class for netdev configuration
+ */
+
+typedef struct lws_netdev_config {
+ void *plat_config;
+} lws_netdev_config_t;
+
+/*
+ * Const Logical generic network interface ops
+ */
+
+typedef struct lws_netdev_ops {
+ struct lws_netdev_instance * (*create)(struct lws_context *ctx,
+ const struct lws_netdev_ops *ops,
+ const char *name, void *platinfo);
+ int (*configure)(struct lws_netdev_instance *nd,
+ lws_netdev_config_t *config);
+ int (*up)(struct lws_netdev_instance *nd);
+ int (*down)(struct lws_netdev_instance *nd);
+ int (*event)(struct lws_netdev_instance *nd, lws_usec_t timestamp,
+ void *buf, size_t len);
+ /**< these are SMD events coming from lws event loop thread context */
+ void (*destroy)(struct lws_netdev_instance **pnd);
+ int (*connect)(struct lws_netdev_instance *wnd, const char *ssid,
+ const char *passphrase, uint8_t *bssid);
+ void (*scan)(struct lws_netdev_instance *nd);
+} lws_netdev_ops_t;
+
+/*
+ * Network devices on this platform
+ *
+ * We also hold a list of all known network credentials (when they are needed
+ * because there is a network interface without anything to connect to) and
+ * the lws_settings instance they are stored in
+ */
+
+typedef struct lws_netdevs {
+ lws_dll2_owner_t owner;
+ /**< list of netdevs / lws_netdev_instance_t -based objects */
+
+ lws_dll2_owner_t owner_creds;
+ /**< list of known credentials */
+ struct lwsac *ac_creds;
+ /**< lwsac holding retreived credentials settings, or NULL */
+ lws_settings_instance_t *si;
+
+ lws_sockaddr46 sa46_dns_resolver;
+
+ uint8_t refcount_creds;
+ /**< when there are multiple netdevs, must refcount creds in mem */
+} lws_netdevs_t;
+
+/*
+ * Base class for an allocated instantiated derived object using lws_netdev_ops,
+ * ie, a specific ethernet device
+ */
+
+typedef struct lws_netdev_instance {
+ const char *name;
+ const lws_netdev_ops_t *ops;
+ void *platinfo;
+ lws_dll2_t list;
+ uint8_t mac[LWS_ETH_ALEN];
+ uint8_t type; /* lws_netdev_type_t */
+} lws_netdev_instance_t;
+
+enum {
+ LNDIW_ALG_OPEN,
+ LNDIW_ALG_WPA2,
+
+ LNDIW_MODE_STA = (1 << 0),
+ LNDIW_MODE_AP = (1 << 1),
+ LNDIW_UP = (1 << 7),
+
+ LNDIW_ACQ_IPv4 = (1 << 0),
+ LNDIW_ACQ_IPv6 = (1 << 1),
+};
+
+/*
+ * Group AP / Station State
+ */
+
+typedef enum {
+ LWSNDVWIFI_STATE_INITIAL,
+ /*
+ * We should gratuitously try whatever last worked for us, then
+ * if that fails, worry about the rest of the logic
+ */
+ LWSNDVWIFI_STATE_SCAN,
+ /*
+ * Unconnected, scanning: AP known in one of the config slots ->
+ * configure it, start timeout + LWSNDVWIFI_STATE_STAT, if no AP
+ * already up in same group with lower MAC, after a random
+ * period start up our AP (LWSNDVWIFI_STATE_AP)
+ */
+ LWSNDVWIFI_STATE_AP,
+ /* Trying to be the group AP... periodically do a scan
+ * LWSNDVWIFI_STATE_AP_SCAN, faster and then slower
+ */
+ LWSNDVWIFI_STATE_AP_SCAN,
+ /*
+ * doing a scan while trying to be the group AP... if we see a
+ * lower MAC being the AP for the same group AP, abandon being
+ * an AP and join that AP as a station
+ */
+ LWSNDVWIFI_STATE_STAT_GRP_AP,
+ /*
+ * We have decided to join another group member who is being the
+ * AP, as its MAC is lower than ours. This is a stable state,
+ * but we still do periodic scans
+ * LWSNDVWIFI_STATE_STAT_GRP_AP_SCAN and will always prefer an
+ * AP configured in a slot.
+ */
+ LWSNDVWIFI_STATE_STAT_GRP_AP_SCAN,
+ /*
+ * We have joined a group member who is doing the AP job... we
+ * want to check every now and then if a configured AP has
+ * appeared that we should better use instead. Otherwise stay
+ * in LWSNDVWIFI_STATE_STAT_GRP_AP
+ */
+ LWSNDVWIFI_STATE_STAT,
+ /*
+ * trying to connect to another non-group AP. If we don't get an
+ * IP within a timeout and retries, mark it as unusable it and go back
+ */
+ LWSNDVWIFI_STATE_STAT_HAPPY,
+} lws_netdev_wifi_state_t;
+
+/*
+ * Generic WIFI credentials
+ */
+
+typedef struct lws_wifi_creds {
+ lws_dll2_t list;
+
+ uint8_t bssid[LWS_ETH_ALEN];
+ char passphrase[64];
+ char ssid[33];
+ uint8_t alg;
+} lws_wifi_creds_t;
+
+/*
+ * Generic WIFI Network Device Instance
+ */
+
+typedef struct lws_netdev_instance_wifi {
+ lws_netdev_instance_t inst;
+ lws_dll2_owner_t scan; /* sorted scan results */
+ lws_sorted_usec_list_t sul_scan;
+
+ lws_wifi_creds_t *ap_cred;
+ const char *ap_ip;
+
+ const char *sta_ads;
+
+ char current_attempt_ssid[33];
+ uint8_t current_attempt_bssid[LWS_ETH_ALEN];
+
+ uint8_t flags;
+ uint8_t state; /* lws_netdev_wifi_state_t */
+} lws_netdev_instance_wifi_t;
+
+/*
+ * Logical scan results sorted list item
+ */
+
+typedef struct lws_wifi_sta {
+ lws_dll2_t list;
+
+ uint32_t last_seen; /* unix time */
+ uint32_t last_tried; /* unix time */
+
+ uint8_t bssid[LWS_ETH_ALEN];
+ char *ssid; /* points to overallocation */
+ uint8_t ssid_len;
+ lws_wifi_ch_t ch;
+ lws_wifi_rssi_t rssi[8];
+ int16_t rssi_avg;
+ uint8_t authmode;
+
+ uint8_t rssi_count;
+ uint8_t rssi_next;
+
+ /* ssid overallocated afterwards */
+} lws_wifi_sta_t;
+
+#define rssi_averaged(_x) (_x->rssi_count ? \
+ ((int)_x->rssi_avg / (int)_x->rssi_count) : \
+ -200)
+
+LWS_VISIBLE LWS_EXTERN lws_netdevs_t *
+lws_netdevs_from_ctx(struct lws_context *ctx);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_netdev_credentials_settings_set(lws_netdevs_t *nds);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_netdev_credentials_settings_get(lws_netdevs_t *nds);
+
+LWS_VISIBLE LWS_EXTERN struct lws_netdev_instance *
+lws_netdev_wifi_create_plat(struct lws_context *ctx,
+ const lws_netdev_ops_t *ops, const char *name,
+ void *platinfo);
+LWS_VISIBLE LWS_EXTERN int
+lws_netdev_wifi_configure_plat(struct lws_netdev_instance *nd,
+ lws_netdev_config_t *config);
+LWS_VISIBLE LWS_EXTERN int
+lws_netdev_wifi_event_plat(struct lws_netdev_instance *nd, lws_usec_t timestamp,
+ void *buf, size_t len);
+LWS_VISIBLE LWS_EXTERN int
+lws_netdev_wifi_up_plat(struct lws_netdev_instance *nd);
+LWS_VISIBLE LWS_EXTERN int
+lws_netdev_wifi_down_plat(struct lws_netdev_instance *nd);
+LWS_VISIBLE LWS_EXTERN void
+lws_netdev_wifi_destroy_plat(struct lws_netdev_instance **pnd);
+LWS_VISIBLE LWS_EXTERN void
+lws_netdev_wifi_scan_plat(lws_netdev_instance_t *nd);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_netdev_wifi_connect_plat(lws_netdev_instance_t *wnd, const char *ssid,
+ const char *passphrase, uint8_t *bssid);
+
+LWS_VISIBLE LWS_EXTERN lws_netdev_instance_t *
+lws_netdev_find(lws_netdevs_t *netdevs, const char *ifname);
+
+#define lws_netdev_wifi_plat_ops \
+ .create = lws_netdev_wifi_create_plat, \
+ .configure = lws_netdev_wifi_configure_plat, \
+ .event = lws_netdev_wifi_event_plat, \
+ .up = lws_netdev_wifi_up_plat, \
+ .down = lws_netdev_wifi_down_plat, \
+ .connect = lws_netdev_wifi_connect_plat, \
+ .scan = lws_netdev_wifi_scan_plat, \
+ .destroy = lws_netdev_wifi_destroy_plat
+
+/*
+ * This is for plat / OS level init that is necessary to be able to use
+ * networking or wifi at all, without mentioning any specific device
+ */
+
+LWS_VISIBLE LWS_EXTERN int
+lws_netdev_plat_init(void);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_netdev_plat_wifi_init(void);
/*
* libwebsockets - small server side websockets and web server implementation
*
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
*/
///@{
-typedef union {
-#if defined(LWS_WITH_IPV6)
- struct sockaddr_in6 sa6;
+#if defined(LWS_ESP_PLATFORM)
+#include <lwip/sockets.h>
#endif
- struct sockaddr_in sa4;
-} lws_sockaddr46;
+
+typedef uint8_t lws_route_uidx_t;
+
+typedef struct lws_dns_score {
+ uint8_t precedence;
+ uint8_t label;
+} lws_dns_score_t;
+
+/*
+ * This represents an entry in the system routing table
+ */
+
+typedef struct lws_route {
+ lws_dll2_t list;
+
+ lws_sockaddr46 src;
+ lws_sockaddr46 dest;
+ lws_sockaddr46 gateway;
+
+ struct lws_route *source; /* when used as lws_dns_sort_t */
+ lws_dns_score_t score; /* when used as lws_dns_sort_t */
+
+ int if_idx;
+ int priority;
+ int ifa_flags; /* if source_ads */
+
+ lws_route_uidx_t uidx; /* unique index for this route */
+
+ uint8_t proto;
+ uint8_t dest_len;
+ uint8_t src_len;
+ uint8_t scope; /* if source_ads */
+ uint8_t af; /* if source_ads */
+
+ uint8_t source_ads:1;
+} lws_route_t;
+
+/*
+ * We reuse the route object as the dns sort granule, so there's only one
+ * struct needs to know all the gnarly ipv6 details
+ */
+
+typedef lws_route_t lws_dns_sort_t;
/**
* lws_canonical_hostname() - returns this host's hostname
* \param sa46a: first
* \param sa46b: second
*
- * Returns 0 if the address family and address are the same, otherwise nonzero.
+ * Returns 0 if the address family is INET or INET6 and the address is the same,
+ * or if the AF is the same but not INET or INET6, otherwise nonzero.
*/
LWS_VISIBLE LWS_EXTERN int
lws_sa46_compare_ads(const lws_sockaddr46 *sa46a, const lws_sockaddr46 *sa46b);
+/**
+ * lws_sa46_on_net() - checks if an sa46 is on the subnet represented by another
+ *
+ * \param sa46a: first
+ * \param sa46_net: network
+ * \param net_len: length of network non-mask
+ *
+ * Returns 0 if sa46a belongs on network sa46_net/net_len
+ *
+ * If there is an ipv4 / v6 mismatch between the ip and the net, the ipv4
+ * address is promoted to ::ffff:x.x.x.x before the comparison.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_sa46_on_net(const lws_sockaddr46 *sa46a, const lws_sockaddr46 *sa46_net,
+ int net_len);
+
/*
* lws_parse_numeric_address() - converts numeric ipv4 or ipv6 to byte address
*
+++ /dev/null
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
- *
- * 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.
- */
-
-/*! \defgroup generic-sessions plugin: generic-sessions
- * \ingroup Protocols-and-Plugins
- *
- * ##Plugin Generic-sessions related
- *
- * generic-sessions plugin provides a reusable, generic session and login /
- * register / forgot password framework including email verification.
- */
-///@{
-
-#define LWSGS_EMAIL_CONTENT_SIZE 16384
-/**< Maximum size of email we might send */
-
-/* SHA-1 binary and hexified versions */
-/** typedef struct lwsgw_hash_bin */
-typedef struct { unsigned char bin[32]; /**< binary representation of hash */} lwsgw_hash_bin;
-/** typedef struct lwsgw_hash */
-typedef struct { char id[65]; /**< ascii hex representation of hash */ } lwsgw_hash;
-
-/** enum lwsgs_auth_bits */
-enum lwsgs_auth_bits {
- LWSGS_AUTH_LOGGED_IN = 1, /**< user is logged in as somebody */
- LWSGS_AUTH_ADMIN = 2, /**< logged in as the admin user */
- LWSGS_AUTH_VERIFIED = 4, /**< user has verified his email */
- LWSGS_AUTH_FORGOT_FLOW = 8, /**< just completed "forgot password" */
-};
-
-/** struct lws_session_info - information about user session status */
-struct lws_session_info {
- char username[32]; /**< username logged in as, or empty string */
- char email[100]; /**< email address associated with login, or empty string */
- char ip[72]; /**< ip address session was started from */
- unsigned int mask; /**< access rights mask associated with session
- * see enum lwsgs_auth_bits */
- char session[42]; /**< session id string, usable as opaque uid when not logged in */
-};
-
-/** enum lws_gs_event */
-enum lws_gs_event {
- LWSGSE_CREATED, /**< a new user was created */
- LWSGSE_DELETED /**< an existing user was deleted */
-};
-
-/** struct lws_gs_event_args */
-struct lws_gs_event_args {
- enum lws_gs_event event; /**< which event happened */
- const char *username; /**< which username the event happened to */
- const char *email; /**< the email address of that user */
-};
-
-///@}
* to the selected protocol. For example if this protocol was
* called "myprotocol-v2", you might set id to 2, and the user
* code that acts differently according to the version can do so by
- * switch (wsi->protocol->id), user code might use some bits as
+ * switch (wsi->a.protocol->id), user code might use some bits as
* capability flags based on selected protocol version, etc. */
void *user; /**< ignored by lws, but user code can pass a pointer
here it can later access from the protocol callback */
const struct lws_protocols *prot);
/**
+ * lws_vhd_find_by_pvo() - find a partner vhd
+ *
+ * \param cx: the lws_context
+ * \param protname: the name of the lws_protocol the vhd belongs to
+ * \param pvo_name: the name of a pvo that must exist bound to the vhd
+ * \param pvo_value: the required value of the named pvo
+ *
+ * This allows architectures with multiple protocols bound together to
+ * cleanly discover partner protocol instances even on completely
+ * different vhosts. For example, a proxy may consist of two protocols
+ * listening on different vhosts, and there may be multiple instances
+ * of the proxy in the same process. It's desirable that each side of
+ * the proxy is an independent protocol that can be freely bound to any
+ * vhost, eg, allowing Unix Domain to tls / h2 proxying, or each side
+ * bound to different network interfaces for localhost-only visibility
+ * on one side, using existing vhost management.
+ *
+ * That leaves the problem that the two sides have to find each other
+ * and bind at runtime. This api allows each side to specify the
+ * protocol name, and a common pvo name and pvo value that indicates
+ * the two sides belong together, and search through all the instantiated
+ * vhost-protocols looking for a match. If found, the private allocation
+ * (aka "vhd" of the match is returned). NULL is returned on no match.
+ *
+ * Since this can only succeed when called by the last of the two
+ * protocols to be instantiated, both sides should call it and handle
+ * NULL gracefully, since it may mean that they were first and their
+ * partner vhsot-protocol has not been instantiated yet.
+ */
+LWS_VISIBLE LWS_EXTERN void *
+lws_vhd_find_by_pvo(struct lws_context *cx, const char *protname,
+ const char *pvo_name, const char *pvo_value);
+
+
+/**
* lws_adjust_protocol_psds - change a vhost protocol's per session data size
*
* \param wsi: a connection with the protocol to change
LWS_VISIBLE LWS_EXTERN int
lws_protocol_init(struct lws_context *context);
-#ifdef LWS_WITH_PLUGINS
+#define LWS_PLUGIN_API_MAGIC 191
-/* PLUGINS implies LIBUV */
+/*
+ * Abstract plugin header for any kind of plugin class, always at top of
+ * actual class plugin export type.
+ *
+ * The export type object must be exported with the same name as the plugin
+ * file, eg, libmyplugin.so must export a const one of these as the symbol
+ * "myplugin".
+ *
+ * That is the only expected export from the plugin.
+ */
-#define LWS_PLUGIN_API_MAGIC 180
+typedef struct lws_plugin_header {
+ const char *name;
+ const char *_class;
+ const char *lws_build_hash; /* set to LWS_BUILD_HASH */
+
+ unsigned int api_magic;
+ /* set to LWS_PLUGIN_API_MAGIC at plugin build time */
+
+ /* plugin-class specific superclass data follows */
+} lws_plugin_header_t;
+
+/*
+ * "lws_protocol_plugin" class export, for lws_protocol implementations done
+ * as plugins
+ */
+typedef struct lws_plugin_protocol {
+ lws_plugin_header_t hdr;
-/** struct lws_plugin_capability - how a plugin introduces itself to lws */
-struct lws_plugin_capability {
- unsigned int api_magic; /**< caller fills this in, plugin fills rest */
const struct lws_protocols *protocols; /**< array of supported protocols provided by plugin */
- int count_protocols; /**< how many protocols */
const struct lws_extension *extensions; /**< array of extensions provided by plugin */
+ int count_protocols; /**< how many protocols */
int count_extensions; /**< how many extensions */
-};
+} lws_plugin_protocol_t;
+
-typedef int (*lws_plugin_init_func)(struct lws_context *,
- struct lws_plugin_capability *);
-typedef int (*lws_plugin_destroy_func)(struct lws_context *);
+/*
+ * This is the dynamic, runtime created part of the plugin instantiation.
+ * These are kept in a linked-list and destroyed with the context.
+ */
-/** struct lws_plugin */
struct lws_plugin {
struct lws_plugin *list; /**< linked list */
+
+ const lws_plugin_header_t *hdr;
+
+ union {
+#if defined(LWS_WITH_LIBUV) && defined(UV_ERRNO_MAP)
#if (UV_VERSION_MAJOR > 0)
- uv_lib_t lib; /**< shared library pointer */
+ uv_lib_t lib; /**< shared library pointer */
#endif
- void *l; /**< so we can compile on ancient libuv */
- char name[64]; /**< name of the plugin */
- struct lws_plugin_capability caps; /**< plugin capabilities */
+#endif
+ void *l; /**< */
+ } u;
};
+/*
+ * Event lib library plugin type (when LWS_WITH_EVLIB_PLUGINS)
+ * Public so new event libs can equally be supported outside lws itself
+ */
+
+typedef struct lws_plugin_evlib {
+ lws_plugin_header_t hdr;
+ const struct lws_event_loop_ops *ops;
+} lws_plugin_evlib_t;
+
+typedef int (*each_plugin_cb_t)(struct lws_plugin *p, void *user);
+
+/**
+ * lws_plugins_init() - dynamically load plugins of matching class from dirs
+ *
+ * \param pplugin: pointer to linked-list for this kind of plugin
+ * \param d: array of directory paths to look in
+ * \param _class: class string that plugin must declare
+ * \param filter: NULL, or a string that must appear after the third char of the plugin filename
+ * \param each: NULL, or each_plugin_cb_t callback for each instantiated plugin
+ * \param each_user: pointer passed to each callback
+ *
+ * Allows you to instantiate a class of plugins to a specified linked-list.
+ * The each callback allows you to init each inistantiated callback and pass a
+ * pointer each_user to it.
+ *
+ * To take down the plugins, pass a pointer to the linked-list head to
+ * lws_plugins_destroy.
+ *
+ * This is used for lws protocol plugins but you can define your own plugin
+ * class name like "mypluginclass", declare it in your plugin headers, and load
+ * your own plugins to your own list using this api the same way.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_plugins_init(struct lws_plugin **pplugin, const char * const *d,
+ const char *_class, const char *filter,
+ each_plugin_cb_t each, void *each_user);
+
+/**
+ * lws_plugins_destroy() - dynamically unload list of plugins
+ *
+ * \param pplugin: pointer to linked-list for this kind of plugin
+ * \param each: NULL, or each_plugin_cb_t callback for each instantiated plugin
+ * \param each_user: pointer passed to each callback
+ *
+ * Allows you to destroy a class of plugins from a specified linked-list
+ * created by a call to lws_plugins_init().
+ *
+ * The each callback allows you to deinit each inistantiated callback and pass a
+ * pointer each_user to it, just before its footprint is destroyed.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_plugins_destroy(struct lws_plugin **pplugin, each_plugin_cb_t each,
+ void *each_user);
+
+#if defined(LWS_WITH_PLUGINS_BUILTIN)
+
+/* provide exports for builtin plugin protocols */
+
+extern const struct lws_protocols post_demo_protocols[1];
+extern const struct lws_protocols lws_raw_proxy_protocols[1];
+extern const struct lws_protocols lws_status_protocols[1];
+extern const struct lws_protocols lws_mirror_protocols[1];
+extern const struct lws_protocols lws_ssh_base_protocols[2];
+extern const struct lws_protocols post_demo_protocols[1];
+extern const struct lws_protocols dumb_increment_protocols[1];
+extern const struct lws_protocols deaddrop_protocols[1];
+extern const struct lws_protocols lws_raw_test_protocols[1];
+extern const struct lws_protocols lws_sshd_demo_protocols[1];
+extern const struct lws_protocols lws_acme_client_protocols[1];
+extern const struct lws_protocols client_loopback_test_protocols[1];
+extern const struct lws_protocols fulltext_demo_protocols[1];
+extern const struct lws_protocols lws_openmetrics_export_protocols[
+#if defined(LWS_WITH_SERVER) && defined(LWS_WITH_CLIENT) && defined(LWS_ROLE_WS)
+ 4
+#else
+#if defined(LWS_WITH_SERVER)
+ 3
+#else
+ 1
+#endif
+#endif
+ ];
+
+#define LWSOMPROIDX_DIRECT_HTTP_SERVER 0
+#define LWSOMPROIDX_PROX_HTTP_SERVER 1
+#define LWSOMPROIDX_PROX_WS_SERVER 2
+#define LWSOMPROIDX_PROX_WS_CLIENT 3
+
#endif
///@}
* possible to do it in-place, ie, with escaped == string
*/
LWS_VISIBLE LWS_EXTERN const char *
-lws_sql_purify(char *escaped, const char *string, int len);
+lws_sql_purify(char *escaped, const char *string, size_t len);
/**
* lws_sql_purify_len() - return length of purified version of input string
LWS_VISIBLE LWS_EXTERN int
lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
- int len);
+ size_t len);
LWS_VISIBLE LWS_EXTERN int
-lws_plat_write_file(const char *filename, void *buf, int len);
+lws_plat_write_file(const char *filename, void *buf, size_t len);
LWS_VISIBLE LWS_EXTERN int
-lws_plat_read_file(const char *filename, void *buf, int len);
+lws_plat_read_file(const char *filename, void *buf, size_t len);
LWS_VISIBLE LWS_EXTERN int
lws_plat_recommended_rsa_bits(void);
--- /dev/null
+/*
+ * Generic PWM controller ops
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ */
+
+typedef struct lws_pwm_map {
+ _lws_plat_gpio_t gpio;
+ uint8_t index;
+ uint8_t active_level;
+} lws_pwm_map_t;
+
+typedef struct lws_pwm_ops {
+ int (*init)(const struct lws_pwm_ops *lo);
+ void (*intensity)(const struct lws_pwm_ops *lo, _lws_plat_gpio_t gpio,
+ lws_led_intensity_t inten);
+ const lws_pwm_map_t *pwm_map;
+ uint8_t count_pwm_map;
+} lws_pwm_ops_t;
+
+LWS_VISIBLE LWS_EXTERN int
+lws_pwm_plat_init(const struct lws_pwm_ops *lo);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_pwm_plat_intensity(const struct lws_pwm_ops *lo, _lws_plat_gpio_t gpio,
+ lws_led_intensity_t inten);
+
+#define lws_pwm_plat_ops \
+ .init = lws_pwm_plat_init, \
+ .intensity = lws_pwm_plat_intensity
+
+/*
+ * May be useful for making your own transitions or sequences
+ */
+
+LWS_VISIBLE LWS_EXTERN lws_led_intensity_t
+lws_led_func_linear(lws_led_seq_phase_t n);
+LWS_VISIBLE LWS_EXTERN lws_led_intensity_t
+lws_led_func_sine(lws_led_seq_phase_t n);
+
+/* canned sequences that can work out of the box */
+
+extern const lws_led_sequence_def_t lws_pwmseq_sine_endless_slow,
+ lws_pwmseq_sine_endless_fast,
+ lws_pwmseq_linear_wipe,
+ lws_pwmseq_sine_up, lws_pwmseq_sine_down,
+ lws_pwmseq_static_on,
+ lws_pwmseq_static_half,
+ lws_pwmseq_static_off;
*/
#if defined(LWS_SS_USE_SSPC)
-#define lws_ss_handle lws_sspc_handle
-#define lws_ss_create lws_sspc_create
-#define lws_ss_destroy lws_sspc_destroy
-#define lws_ss_request_tx lws_sspc_request_tx
-#define lws_ss_client_connect lws_sspc_client_connect
-#define lws_ss_get_sequencer lws_sspc_get_sequencer
-#define lws_ss_proxy_create lws_sspc_proxy_create
-#define lws_ss_get_context lws_sspc_get_context
-#define lws_ss_rideshare lws_sspc_rideshare
-#define lws_ss_set_metadata lws_sspc_set_metadata
-#define lws_ss_add_peer_tx_credit lws_sspc_add_peer_tx_credit
-#define lws_ss_get_est_peer_tx_credit lws_sspc_get_est_peer_tx_credit
+#define lws_ss_handle lws_sspc_handle
+#define lws_ss_create lws_sspc_create
+#define lws_ss_destroy lws_sspc_destroy
+#define lws_ss_request_tx lws_sspc_request_tx
+#define lws_ss_request_tx_len lws_sspc_request_tx_len
+#define lws_ss_client_connect lws_sspc_client_connect
+#define lws_ss_get_sequencer lws_sspc_get_sequencer
+#define lws_ss_proxy_create lws_sspc_proxy_create
+#define lws_ss_get_context lws_sspc_get_context
+#define lws_ss_rideshare lws_sspc_rideshare
+#define lws_ss_set_metadata lws_sspc_set_metadata
+#define lws_ss_get_metadata lws_sspc_get_metadata
+#define lws_ss_add_peer_tx_credit lws_sspc_add_peer_tx_credit
+#define lws_ss_get_est_peer_tx_credit lws_sspc_get_est_peer_tx_credit
+#define lws_ss_start_timeout lws_sspc_start_timeout
+#define lws_ss_cancel_timeout lws_sspc_cancel_timeout
+#define lws_ss_to_user_object lws_sspc_to_user_object
+#define lws_ss_change_handlers lws_sspc_change_handlers
+#define lws_smd_ss_rx_forward lws_smd_sspc_rx_forward
+#define lws_ss_tag lws_sspc_tag
+#define _lws_fi_user_ss_fi _lws_fi_user_sspc_fi
#endif
LWS_VISIBLE LWS_EXTERN int
lws_sspc_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
- void *opaque_user_data, struct lws_sspc_handle **ppss,
- struct lws_sequencer *seq_owner, const char **ppayload_fmt);
+ void *opaque_user_data, struct lws_sspc_handle **ppss,
+ struct lws_sequencer *seq_owner, const char **ppayload_fmt);
/**
* lws_sspc_destroy() - Destroy secure stream
* write on this stream, the *tx callback will occur with an empty buffer for
* the stream owner to fill in.
*/
-LWS_VISIBLE LWS_EXTERN void
+LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
lws_sspc_request_tx(struct lws_sspc_handle *pss);
/**
+ * lws_sspc_request_tx_len() - Schedule stream for tx with length hint
+ *
+ * \param h: pointer to handle representing stream that wants to transmit
+ * \param len: the length of the write in bytes
+ *
+ * Schedules a write on the stream represented by \p pss. When it's possible to
+ * write on this stream, the *tx callback will occur with an empty buffer for
+ * the stream owner to fill in.
+ *
+ * This api variant should be used when it's possible the payload will go out
+ * over h1 with x-web-form-urlencoded or similar Content-Type.
+ *
+ * The serialized, sspc type api actually serializes and forwards the length
+ * hint to its upstream proxy, where it's available for use to produce the
+ * internet-capable protocol framing.
+ */
+LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
+lws_sspc_request_tx_len(struct lws_sspc_handle *h, unsigned long len);
+
+/**
* lws_sspc_client_connect() - Attempt the client connect
*
* \param h: secure streams handle
* Starts the connection process for the secure stream. Returns 0 if OK or
* nonzero if we have already failed.
*/
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
lws_sspc_client_connect(struct lws_sspc_handle *h);
/**
LWS_VISIBLE LWS_EXTERN struct lws_context *
lws_sspc_get_context(struct lws_sspc_handle *h);
-LWS_VISIBLE LWS_EXTERN const struct lws_protocols lws_sspc_protocols[];
+LWS_VISIBLE extern const struct lws_protocols lws_sspc_protocols[2];
LWS_VISIBLE LWS_EXTERN const char *
lws_sspc_rideshare(struct lws_sspc_handle *h);
*/
LWS_VISIBLE LWS_EXTERN int
lws_sspc_set_metadata(struct lws_sspc_handle *h, const char *name,
- void *value, size_t len);
+ const void *value, size_t len);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_sspc_get_metadata(struct lws_sspc_handle *h, const char *name,
+ const void **value, size_t *len);
LWS_VISIBLE LWS_EXTERN int
lws_sspc_add_peer_tx_credit(struct lws_sspc_handle *h, int32_t add);
LWS_VISIBLE LWS_EXTERN int
lws_sspc_get_est_peer_tx_credit(struct lws_sspc_handle *h);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_sspc_start_timeout(struct lws_sspc_handle *h, unsigned int timeout_ms);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_sspc_cancel_timeout(struct lws_sspc_handle *h);
+
+LWS_VISIBLE LWS_EXTERN void *
+lws_sspc_to_user_object(struct lws_sspc_handle *h);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_sspc_change_handlers(struct lws_sspc_handle *h,
+ lws_ss_state_return_t (*rx)(void *userobj, const uint8_t *buf,
+ size_t len, int flags),
+ lws_ss_state_return_t (*tx)(void *userobj, lws_ss_tx_ordinal_t ord,
+ uint8_t *buf, size_t *len, int *flags),
+ lws_ss_state_return_t (*state)(void *userobj, void *h_src
+ /* ss handle type */,
+ lws_ss_constate_t state,
+ lws_ss_tx_ordinal_t ack));
+
+const char *
+lws_sspc_tag(struct lws_sspc_handle *h);
* has the LWSSSPOLF_NAILED_UP flag.
*/
+#if defined(LWS_WITH_SSPLUGINS)
typedef struct lws_ss_plugin {
struct lws_ss_plugin *next;
const char *name; /**< auth plugin name */
add http headers) this callback will give
it the opportunity to do so */
} lws_ss_plugin_t;
+#endif
+/* the public, const metrics policy definition */
+
+typedef struct lws_metric_policy {
+ /* order of first two mandated by JSON policy parsing scope union */
+ const struct lws_metric_policy *next;
+ const char *name;
+
+ const char *report;
+
+ /**< the metrics policy name in the policy, used to bind to it */
+ uint64_t us_schedule;
+ /**< us interval between lws_system metrics api reports */
+
+ uint32_t us_decay_unit;
+ /**< how many us to decay avg by half, 0 = no decay */
+ uint8_t min_contributors;
+ /**< before we can judge something is an outlier */
+} lws_metric_policy_t;
typedef struct lws_ss_x509 {
struct lws_ss_x509 *next;
const char *vhost_name; /**< vhost name using cert ctx */
const uint8_t *ca_der; /**< DER x.509 cert */
size_t ca_der_len; /**< length of DER cert */
+ uint8_t keep:1; /**< ie, if used in server tls */
} lws_ss_x509_t;
enum {
/**< set up lws_system client cert */
LWSSSPOLF_LOCAL_SINK = (1 << 13),
/**< expected to bind to a local sink only */
+ LWSSSPOLF_WAKE_SUSPEND__VALIDITY = (1 << 14),
+ /**< this stream's idle validity checks are critical enough we
+ * should arrange to wake from suspend to perform them
+ */
+ LWSSSPOLF_SERVER = (1 << 15),
+ /**< we listen on a socket as a server */
+ LWSSSPOLF_ALLOW_REDIRECTS = (1 << 16),
+ /**< follow redirects */
+ LWSSSPOLF_HTTP_MULTIPART_IN = (1 << 17),
+ /**< handle inbound multipart mime at SS level */
+
+ LWSSSPOLF_ATTR_LOW_LATENCY = (1 << 18),
+ /**< stream requires low latency */
+ LWSSSPOLF_ATTR_HIGH_THROUGHPUT = (1 << 19),
+ /**< stream requires high throughput */
+ LWSSSPOLF_ATTR_HIGH_RELIABILITY = (1 << 20),
+ /**< stream requires high reliability */
+ LWSSSPOLF_ATTR_LOW_COST = (1 << 21),
+ /**< stream is not critical and should be handled as cheap as poss */
+ LWSSSPOLF_PERF = (1 << 22),
+ /**< capture and report performace information */
};
typedef struct lws_ss_trust_store {
struct lws_ss_trust_store *next;
const char *name;
- lws_ss_x509_t *ssx509[8];
+ const lws_ss_x509_t *ssx509[6];
int count;
} lws_ss_trust_store_t;
LWSSSP_H1,
LWSSSP_H2,
LWSSSP_WS,
+ LWSSSP_MQTT,
+ LWSSSP_RAW,
LWSSS_HBI_AUTH = 0,
_LWSSS_HBI_COUNT /* always last */
};
+/*
+ * This does for both the static policy metadata entry, and the runtime metadata
+ * handling object.
+ */
+
typedef struct lws_ss_metadata {
struct lws_ss_metadata *next;
const char *name;
- void *value;
+ void *value__may_own_heap;
size_t length;
- uint8_t value_on_lws_heap; /* proxy does this */
+ uint8_t value_length; /* only valid if set by policy */
+ uint8_t value_is_http_token; /* valid if set by policy */
+ uint8_t value_on_lws_heap:1; /* proxy + rx metadata does this */
+#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
+ uint8_t pending_onward:1;
+#endif
} lws_ss_metadata_t;
+typedef struct lws_ss_http_respmap {
+ uint16_t resp; /* the http response code */
+ uint16_t state; /* low 16-bits of associated state */
+} lws_ss_http_respmap_t;
+
+/*
+ * This is a mapping between an auth streamtype and a name and other information
+ * that can be independently instantiated. Other streamtypes can indicate they
+ * require this authentication on their connection.
+ */
+
+typedef struct lws_ss_auth {
+ struct lws_ss_auth *next;
+ const char *name;
+
+ const char *type;
+ const char *streamtype;
+ uint8_t blob_index;
+} lws_ss_auth_t;
/**
* lws_ss_policy_t: policy database entry for a stream type
const char *payload_fmt;
const char *socks5_proxy;
lws_ss_metadata_t *metadata; /* linked-list of metadata */
+ const lws_metric_policy_t *metrics; /* linked-list of metric policies */
+ const lws_ss_auth_t *auth; /* NULL or auth object we bind to */
/* protocol-specific connection policy details */
union {
+#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) || defined(LWS_ROLE_WS)
+
/* details for http-related protocols... */
struct {
const char *blob_header[_LWSSS_HBI_COUNT];
const char *auth_preamble;
+ const lws_ss_http_respmap_t *respmap;
+
union {
// struct { /* LWSSSP_H1 */
// } h1;
/* false = TEXT, true = BINARY */
} ws;
} u;
+
+ uint16_t resp_expect;
+ uint8_t count_respmap;
+ uint8_t fail_redirect:1;
} http;
+#endif
+
+#if defined(LWS_ROLE_MQTT)
+
struct {
const char *topic; /* stream sends on this topic */
const char *subscribe; /* stream subscribes to this topic */
uint8_t clean_start;
uint8_t will_qos;
uint8_t will_retain;
+ uint8_t aws_iot;
} mqtt;
+#endif
+
/* details for non-http related protocols... */
} u;
+#if defined(LWS_WITH_SSPLUGINS)
const
struct lws_ss_plugin *plugins[2]; /**< NULL or auth plugin */
const void *plugins_info[2]; /**< plugin-specific data */
+#endif
+
+#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
+ /* directly point to the metadata name, no need to expand */
+ const char *aws_region;
+ const char *aws_service;
+#endif
+ /*
+ * We're either a client connection policy that wants a trust store,
+ * or we're a server policy that wants a mem cert and key... Hold
+ * these mutually-exclusive things in a union.
+ */
- const lws_ss_trust_store_t *trust_store; /**< CA certs needed for conn
- validation, only set between policy parsing and vhost creation */
+ union {
+ const lws_ss_trust_store_t *store;
+ /**< CA certs needed for conn validation, only set between
+ * policy parsing and vhost creation */
+ struct {
+ const lws_ss_x509_t *cert;
+ /**< the server's signed cert with the pubkey */
+ const lws_ss_x509_t *key;
+ /**< the server's matching private key */
+ } server;
+ } trust;
const lws_retry_bo_t *retry_bo; /**< retry policy to use */
+ uint32_t proxy_buflen; /**< max dsh alloc for proxy */
+ uint32_t proxy_buflen_rxflow_on_above;
+ uint32_t proxy_buflen_rxflow_off_below;
+
+ uint32_t client_buflen; /**< max dsh alloc for client */
+ uint32_t client_buflen_rxflow_on_above;
+ uint32_t client_buflen_rxflow_off_below;
+
+
+ uint32_t timeout_ms; /**< default message response
+ * timeout in ms */
uint32_t flags; /**< stream attribute flags */
uint16_t port; /**< endpoint port */
uint8_t protocol; /**< protocol index */
uint8_t client_cert; /**< which client cert to apply
0 = none, 1+ = cc 0+ */
+ uint8_t priority; /* 0 = normal, 6 = max normal,
+ * 7 = network management */
} lws_ss_policy_t;
+
+#if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
+
+/*
+ * These only exist / have meaning if there's a dynamic JSON policy enabled
+ */
+
+LWS_VISIBLE LWS_EXTERN int
+lws_ss_policy_parse_begin(struct lws_context *context, int overlay);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_ss_policy_parse_abandon(struct lws_context *context);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_ss_policy_parse(struct lws_context *context, const uint8_t *buf, size_t len);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_ss_policy_overlay(struct lws_context *context, const char *overlay);
+
+/*
+ * You almost certainly don't want these, they return the first policy or auth
+ * object in a linked-list of objects created by lws_ss_policy_parse above,
+ * they are exported to generate static policy with
+ */
+LWS_VISIBLE LWS_EXTERN const lws_ss_policy_t *
+lws_ss_policy_get(struct lws_context *context);
+
+LWS_VISIBLE LWS_EXTERN const lws_ss_auth_t *
+lws_ss_auth_get(struct lws_context *context);
+
+#endif
*
* - 0: LWSSS_SER_TXPRE_STREAMTYPE
* - 1: 2-byte MSB-first rest-of-frame length
- * - 3: 4 byte MSB-first initial tx credit
- * - 7: the streamtype name with no NUL
+ * - 3: 1-byte Client SSS protocol version (introduced in SSSv1)
+ * - 4: 4-byte Client PID (introduced in SSSv1)
+ * - 8: 4-byte MSB-first initial tx credit
+ * - 12: the streamtype name with no NUL
*
* - Proxied tx
*
* - 3: 4-byte MSB-first flags
* - 7: 4-byte MSB-first us between client requested write and wrote to proxy
* - 11: 8-byte MSB-first us resolution unix time client wrote to proxy
- * - 17: payload
+ * - 19: payload
*
* - Proxied secure stream destroy
*
*
* - 0: LWSSS_SER_TXPRE_METADATA
* - 1: 2-byte MSB-first rest-of-frame length
- * - 2: 1-byte metadata name length
- * - 3: metadata name
+ * - 3: 1-byte metadata name length
+ * - 4: metadata name
* - ...: metadata value (for rest of packet)
*
+ * - TX credit management - sent when using tx credit apis, cf METADATA
+ *
+ * - 0: LWSSS_SER_TXPRE_TXCR_UPDATE
+ * - 1: 2-byte MSB-first rest-of-frame length 00, 04
+ * - 3: 4-byte additional tx credit adjust value
+ *
+ * - Stream timeout management - forwarded when user applying or cancelling t.o.
+ *
+ * - 0: LWSSS_SER_TXPRE_TIMEOUT_UPDATE
+ * - 1: 2-byte MSB-first rest-of-frame length 00, 04
+ * - 3: 4-byte MSB-first unsigned 32-bit timeout, 0 = use policy, -1 = cancel
+ *
+ * - Passing up payload length hint
+ *
+ * - 0: LWSSS_SER_TXPRE_PAYLOAD_LENGTH_HINT
+ * - 1: 2-byte MSB-first rest-of-frame length 00, 04
+ * - 3: 4-byte MSB-first unsigned 32-bit payload length hint
+ *
* Proxy to client
*
* - Proxied connection setup result
* - 0: LWSSS_SER_RXPRE_CREATE_RESULT
* - 1: 2 byte MSB-first rest-of-frame length (usually 00, 03)
* - 3: 1 byte result, 0 = success. On failure, proxy will close connection.
- * - 4: 2 byte MSB-first initial tx credit
- * - 6: if present, comma-sep list of rideshare types from policy
+ * - 4: 4 byte client dsh allocation recommended for stream type, from policy
+ * (introduced in SSSv1)
+ * - 8: 2 byte MSB-first initial tx credit
+ * - 10: if present, comma-sep list of rideshare types from policy
*
* - Proxied rx
*
* - 1: 00, 04
* - 3: 4-byte MSB-first addition tx credit bytes
*
- * - Proxied state
+ * - Proxied rx metadata
+ *
+ * - 0: LWSSS_SER_RXPRE_METADATA
+ * - 1: 2-byte MSB-first rest-of-frame length
+ * - 3: 1-byte metadata name length
+ * - 4: metadata name
+ * - ...: metadata value (for rest of packet)
+ *
+ * - Proxied state (8 or 11 byte packet)
*
* - 0: LWSSS_SER_RXPRE_CONNSTATE
- * - 1: 00, 05
- * - 3: 1 byte state index
- * - 7: 4-byte MSB-first ordinal
+ * - 1: 00, 05 if state < 256, else 00, 08
+ * - 3: 1 byte state index if state < 256, else 4-byte MSB-first state index
+ * - 4 or 7: 4-byte MSB-first ordinal
*
+ * - Proxied performance information
+ *
+ * - 0: LWSSS_SER_RXPRE_PERF
+ * - 1: 2-byte MSB-first rest-of-frame length
+ * - 3: ... performance JSON (for rest of packet)
*
* Proxied tx may be read by the proxy but rejected due to lack of buffer space
* at the proxy. For that reason, tx must be held at the sender until it has
* (*rx) with the client stream's
*/
+/** \defgroup secstr Secure Streams
+* ##Secure Streams
+*
+* Secure Streams related apis
+*/
+///@{
+
#define LWS_SS_MTU 1540
struct lws_ss_handle;
/*
* connection state events
+ *
+ * If you add states, take care about the state names and state transition
+ * validity enforcement tables too
*/
typedef enum {
- LWSSSCS_CREATING,
+ /* zero means unset */
+ LWSSSCS_CREATING = 1,
LWSSSCS_DISCONNECTED,
- LWSSSCS_UNREACHABLE,
+ LWSSSCS_UNREACHABLE, /* oridinal arg = 1 = caused by dns
+ * server reachability failure */
LWSSSCS_AUTH_FAILED,
LWSSSCS_CONNECTED,
LWSSSCS_CONNECTING,
LWSSSCS_QOS_NACK_REMOTE,
LWSSSCS_QOS_ACK_LOCAL, /* local proxy accepted our tx */
LWSSSCS_QOS_NACK_LOCAL, /* local proxy refused our tx */
+ LWSSSCS_TIMEOUT, /* optional timeout timer fired */
+
+ LWSSSCS_SERVER_TXN,
+ LWSSSCS_SERVER_UPGRADE, /* the server protocol upgraded */
LWSSSCS_SINK_JOIN, /* sinks get this when a new source
* stream joins the sink */
LWSSSCS_SINK_PART, /* sinks get this when a new source
* stream leaves the sink */
+
+ LWSSSCS_USER_BASE = 1000
} lws_ss_constate_t;
enum {
LWSSS_FLAG_RIDESHARE = (1 << 5),
/* Serialized payload starts with non-default rideshare name length and
* name string without NUL, then payload */
+ LWSSS_FLAG_PERF_JSON = (1 << 6),
+ /* This RX is JSON performance data, only on streams with "perf" flag
+ * set */
/*
* In the case the secure stream is proxied across a process or thread
LWSSS_SER_RXPRE_CREATE_RESULT,
LWSSS_SER_RXPRE_CONNSTATE,
LWSSS_SER_RXPRE_TXCR_UPDATE,
+ LWSSS_SER_RXPRE_METADATA,
LWSSS_SER_RXPRE_TLSNEG_ENCLAVE_SIGN,
+ LWSSS_SER_RXPRE_PERF,
/* tx (send by client) prepends for proxied connections */
LWSSS_SER_TXPRE_TX_PAYLOAD,
LWSSS_SER_TXPRE_METADATA,
LWSSS_SER_TXPRE_TXCR_UPDATE,
+ LWSSS_SER_TXPRE_TIMEOUT_UPDATE,
+ LWSSS_SER_TXPRE_PAYLOAD_LENGTH_HINT,
LWSSS_SER_TXPRE_TLSNEG_ENCLAVE_SIGNED,
};
typedef enum {
- LPCS_WAIT_INITIAL_TX = 1, /* after connect, must send streamtype */
- LPCS_REPORTING_FAIL, /* stream creation failed, wait to to tell */
- LPCS_REPORTING_OK, /* stream creation succeeded, wait to to tell */
- LPCS_OPERATIONAL, /* ready for payloads */
- LPCS_DESTROYED,
+ LPCSPROX_WAIT_INITIAL_TX = 1, /* after connect, must send streamtype */
+ LPCSPROX_REPORTING_FAIL, /* stream creation failed, wait to to tell */
+ LPCSPROX_REPORTING_OK, /* stream creation succeeded, wait to to tell */
+ LPCSPROX_OPERATIONAL, /* ready for payloads */
+ LPCSPROX_DESTROYED,
- LPCS_SENDING_INITIAL_TX = 1, /* after connect, must send streamtype */
- LPCS_WAITING_CREATE_RESULT, /* wait to hear if proxy ss create OK */
- LPCS_LOCAL_CONNECTED, /* we are in touch with the proxy */
- LPCS_ONWARD_CONNECT, /* request onward ss connection */
+ LPCSCLI_SENDING_INITIAL_TX, /* after connect, must send streamtype */
+ LPCSCLI_WAITING_CREATE_RESULT, /* wait to hear if proxy ss create OK */
+ LPCSCLI_LOCAL_CONNECTED, /* we are in touch with the proxy */
+ LPCSCLI_ONWARD_CONNECT, /* request onward ss connection */
+ LPCSCLI_OPERATIONAL, /* ready for payloads */
} lws_ss_conn_states_t;
+/*
+ * Returns from state() callback can tell the caller what the user code
+ * wants to do
+ */
+
+typedef enum lws_ss_state_return {
+ LWSSSSRET_TX_DONT_SEND = 1, /* (*tx) only, or failure */
+
+ LWSSSSRET_OK = 0, /* no error */
+ LWSSSSRET_DISCONNECT_ME = -1, /* caller should disconnect us */
+ LWSSSSRET_DESTROY_ME = -2, /* caller should destroy us */
+} lws_ss_state_return_t;
+
/**
* lws_ss_info_t: information about stream to be created
*
* to create the requested stream.
*/
+enum {
+ LWSSSINFLAGS_REGISTER_SINK = (1 << 0),
+ /**< If set, we're not creating a specific stream, but registering
+ * ourselves as the "sink" for .streamtype. It's analogous to saying
+ * we want to be the many-to-one "server" for .streamtype; when other
+ * streams are created with that streamtype, they should be forwarded
+ * to this stream owner, where they join and part from the sink via
+ * (*state) LWSSSCS_SINK_JOIN / _PART events, the new client handle
+ * being provided in the h_src parameter.
+ */
+ LWSSSINFLAGS_PROXIED = (1 << 1),
+ /**< Set if the stream is being created as a stand-in at the proxy */
+ LWSSSINFLAGS_SERVER = (1 << 2),
+ /**< Set on the server object copy of the ssi / info to indicate that
+ * stream creation using this ssi is for Accepted connections belonging
+ * to a server */
+ LWSSSINFLAGS_ACCEPTED = (1 << 3),
+ /**< Set on the accepted object copy of the ssi / info to indicate that
+ * we are an accepted connection from a server's listening socket */
+};
+
+typedef lws_ss_state_return_t (*lws_sscb_rx)(void *userobj, const uint8_t *buf,
+ size_t len, int flags);
+typedef lws_ss_state_return_t (*lws_sscb_tx)(void *userobj,
+ lws_ss_tx_ordinal_t ord,
+ uint8_t *buf, size_t *len,
+ int *flags);
+typedef lws_ss_state_return_t (*lws_sscb_state)(void *userobj, void *h_src,
+ lws_ss_constate_t state,
+ lws_ss_tx_ordinal_t ack);
+
+struct lws_ss_policy;
+
typedef struct lws_ss_info {
const char *streamtype; /**< type of stream we want to create */
size_t user_alloc; /**< size of user allocation */
/**< offset of opaque user data ptr in user_alloc type, set to
offsetof(mytype, opaque_ud_member) */
- int (*rx)(void *userobj, const uint8_t *buf, size_t len,
- int flags);
+#if defined(LWS_WITH_SECURE_STREAMS_CPP)
+ const struct lws_ss_policy *policy;
+ /**< Normally NULL, or a locally-generated policy to apply to this
+ * connection instead of a named streamtype */
+#endif
+
+#if defined(LWS_WITH_SYS_FAULT_INJECTION)
+ lws_fi_ctx_t fic;
+ /**< Attach external Fault Injection context to the stream, hierarchy
+ * is ss->context */
+#endif
+
+ lws_sscb_rx rx;
/**< callback with rx payload for this stream */
- int (*tx)(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf,
- size_t *len, int *flags);
+ lws_sscb_tx tx;
/**< callback to send payload on this stream... 0 = send as set in
* len and flags, 1 = do not send anything (ie, not even 0 len frame) */
- int (*state)(void *userobj, void *h_src /* ss handle type */,
- lws_ss_constate_t state, lws_ss_tx_ordinal_t ack);
+ lws_sscb_state state;
/**< advisory cb about state of stream and QoS status if applicable...
* h_src is only used with sinks and LWSSSCS_SINK_JOIN/_PART events.
* Return nonzero to indicate you want to destroy the stream. */
int manual_initial_tx_credit;
/**< 0 = manage any tx credit automatically, nonzero explicitly sets the
* peer stream to have the given amount of tx credit, if the protocol
- * can support it. */
- char register_sink;
- /**< If set, we're not creating a specific stream, but registering
- * ourselves as the "sink" for .streamtype. It's analogous to saying
- * we want to be the many-to-one "server" for .streamtype; when other
- * streams are created with that streamtype, they should be forwarded
- * to this stream owner, where they join and part from the sink via
- * (*state) LWSSSCS_SINK_JOIN / _PART events, the new client handle
- * being provided in the h_src parameter.
+ * can support it.
+ *
+ * In the special case of _lws_smd streamtype, this is used to indicate
+ * the connection's rx class mask.
+ * */
+ uint32_t client_pid;
+ /**< used in proxy / serialization case to hold the client pid this
+ * proxied connection is to be tagged with
+ */
+ uint8_t flags;
+ uint8_t sss_protocol_version;
+ /**< used in proxy / serialization case to hold the SS serialization
+ * protocol level to use with this peer... clients automatically request
+ * the most recent version they were built with
+ * (LWS_SSS_CLIENT_PROTOCOL_VERSION) and the proxy stores the requested
+ * version in here
*/
+
} lws_ss_info_t;
/**
* name from the policy
*
* Requests a new secure stream described by \p ssi be created. If successful,
- * the stream is created, its state callback called with LWSSSCS_CREATING, *ppss
+ * the stream is created, its state callback called with LWSSSCS_CREATING, \p *ppss
* is set to point to the handle, and it returns 0. If it failed, it returns
* nonzero.
*
*
* \param ppss: pointer to lws_ss_t pointer to be destroyed
*
- * Destroys the lws_ss_t pointed to by *ppss, and sets *ppss to NULL.
+ * Destroys the lws_ss_t pointed to by \p *ppss, and sets \p *ppss to NULL.
*/
LWS_VISIBLE LWS_EXTERN void
lws_ss_destroy(struct lws_ss_handle **ppss);
* \param pss: pointer to lws_ss_t representing stream that wants to transmit
*
* Schedules a write on the stream represented by \p pss. When it's possible to
- * write on this stream, the *tx callback will occur with an empty buffer for
+ * write on this stream, the \p *tx callback will occur with an empty buffer for
* the stream owner to fill in.
+ *
+ * Returns 0 or LWSSSSRET_SS_HANDLE_DESTROYED
*/
-LWS_VISIBLE LWS_EXTERN void
+LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
lws_ss_request_tx(struct lws_ss_handle *pss);
/**
* \param len: the length of the write in bytes
*
* Schedules a write on the stream represented by \p pss. When it's possible to
- * write on this stream, the *tx callback will occur with an empty buffer for
+ * write on this stream, the \p *tx callback will occur with an empty buffer for
* the stream owner to fill in.
*
* This api variant should be used when it's possible the payload will go out
* over h1 with x-web-form-urlencoded or similar Content-Type.
*/
-LWS_VISIBLE LWS_EXTERN void
+LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
lws_ss_request_tx_len(struct lws_ss_handle *pss, unsigned long len);
-
/**
* lws_ss_client_connect() - Attempt the client connect
*
* \param h: secure streams handle
*
- * Starts the connection process for the secure stream. Returns 0 if OK or
- * nonzero if we have already failed.
+ * Starts the connection process for the secure stream.
+ *
+ * Can return any of the lws_ss_state_return_t values depending on user
+ * state callback returns.
+ *
+ * LWSSSSRET_OK means the connection is ongoing.
+ *
*/
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t
lws_ss_client_connect(struct lws_ss_handle *h);
/**
LWS_VISIBLE LWS_EXTERN struct lws_context *
lws_ss_get_context(struct lws_ss_handle *h);
+#define LWSSS_TIMEOUT_FROM_POLICY 0
+
+/**
+ * lws_ss_start_timeout() - start or restart the timeout on the stream
+ *
+ * \param h: secure streams handle
+ * \param timeout_ms: LWSSS_TIMEOUT_FROM_POLICY for policy value, else use timeout_ms
+ *
+ * Starts or restarts the stream's own timeout timer. If the specified time
+ * passes without lws_ss_cancel_timeout() being called on the stream, then the
+ * stream state callback receives LWSSSCS_TIMEOUT
+ *
+ * The process being protected by the timeout is up to the user code, it may be
+ * arbitrarily long and cross multiple protocol transactions or involve other
+ * streams. It's up to the user to decide when to start and when / if to cancel
+ * the stream timeout.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_ss_start_timeout(struct lws_ss_handle *h, unsigned int timeout_ms);
+
+/**
+ * lws_ss_cancel_timeout() - remove any timeout on the stream
+ *
+ * \param h: secure streams handle
+ *
+ * Disable any timeout that was applied to the stream by lws_ss_start_timeout().
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_ss_cancel_timeout(struct lws_ss_handle *h);
+
+/**
+ * lws_ss_to_user_object() - convenience helper to get user object from handle
+ *
+ * \param h: secure streams handle
+ *
+ * Returns the user allocation related to the handle. Normally you won't need
+ * this since it's available in the rx, tx and state callbacks as "userdata"
+ * already.
+ */
+LWS_VISIBLE LWS_EXTERN void *
+lws_ss_to_user_object(struct lws_ss_handle *h);
+
/**
* lws_ss_rideshare() - find the current streamtype when types rideshare
*
* name with the value of the metadata on the left.
*
* Return 0 if OK or nonzero if, eg, metadata name does not exist on the
- * streamtype.
+ * streamtype. You must check the result of this, eg, transient OOM can cause
+ * these to fail and you should retry later.
*/
-LWS_VISIBLE LWS_EXTERN int
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
- void *value, size_t len);
+ const void *value, size_t len);
+/**
+ * lws_ss_alloc_set_metadata() - copy data and bind to ss metadata
+ *
+ * \param h: secure streams handle
+ * \param name: metadata name from the policy
+ * \param value: pointer to user-managed data to bind to name
+ * \param len: length of the user-managed data in value
+ *
+ * Same as lws_ss_set_metadata(), but allocates a heap buffer for the data
+ * first and takes a copy of it, so the original can go out of scope
+ * immediately after.
+ */
+LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
+lws_ss_alloc_set_metadata(struct lws_ss_handle *h, const char *name,
+ const void *value, size_t len);
+
+/**
+ * lws_ss_get_metadata() - get current value of stream metadata item
+ *
+ * \param h: secure streams handle
+ * \param name: metadata name from the policy
+ * \param value: pointer to pointer to be set to point at the value
+ * \param len: pointer to size_t to set to the length of the value
+ *
+ * Binds user-managed data to the named metadata item from the ss policy.
+ * If present, the metadata item is handled in a protocol-specific way using
+ * the associated policy information. For example, in the policy
+ *
+ * "\"metadata\":" "["
+ * "{\"uptag\":" "\"X-Upload-Tag:\"},"
+ * "{\"ctype\":" "\"Content-Type:\"},"
+ * "{\"xctype\":" "\"\"}"
+ * "],"
+ *
+ * when the policy is using h1 is interpreted to add h1 headers of the given
+ * name with the value of the metadata on the left.
+ *
+ * Return 0 if \p *value and \p *len set OK, or nonzero if, eg, metadata \p name does
+ * not exist on the streamtype.
+ *
+ * The pointed-to values may only exist until the next time around the event
+ * loop.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
+ const void **value, size_t *len);
+
+/**
+ * lws_ss_server_ack() - indicate how we feel about what the server has sent
+ *
+ * \param h: ss handle of accepted connection
+ * \param nack: 0 means we are OK with it, else some problem
+ *
+ * For SERVER secure streams
+ *
+ * Depending on the protocol, the server sending us something may be
+ * transactional, ie, built into it sending something is the idea we will
+ * respond somehow out-of-band; HTTP is like this with, eg, 200 response code.
+ *
+ * Calling this with nack=0 indicates that when we later respond, we want to
+ * acknowledge the transaction (eg, it means a 200 if http underneath), if
+ * nonzero that the transaction should act like it failed.
+ *
+ * If the underlying protocol doesn't understand transactions (eg, ws) then this
+ * has no effect either way.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_ss_server_ack(struct lws_ss_handle *h, int nack);
+
+typedef void (*lws_sssfec_cb)(struct lws_ss_handle *h, void *arg);
+
+/**
+ * lws_ss_server_foreach_client() - callback for each live client connected to server
+ *
+ * \param h: server ss handle
+ * \param cb: the callback
+ * \param arg: arg passed to callback
+ *
+ * For SERVER secure streams
+ *
+ * Call the callback \p cb once for each client ss connected to the server,
+ * passing \p arg as an additional callback argument each time.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_ss_server_foreach_client(struct lws_ss_handle *h, lws_sssfec_cb cb,
+ void *arg);
+
+/**
+ * lws_ss_change_handlers() - helper for dynamically changing stream handlers
+ *
+ * \param h: ss handle
+ * \param rx: the new RX handler
+ * \param tx: the new TX handler
+ * \param state: the new state handler
+ *
+ * Handlers set to NULL are left unchanged.
+ *
+ * This works on any handle, client or server and takes effect immediately.
+ *
+ * Depending on circumstances this may be helpful when
+ *
+ * a) a server stream undergoes an LWSSSCS_SERVER_UPGRADE (as in http -> ws) and
+ * the payloads in the new protocol have a different purpose that is best
+ * handled in their own rx and tx callbacks, and
+ *
+ * b) you may want to serve several different, possibly large things based on
+ * what was requested. Setting a customized handler allows clean encapsulation
+ * of the different serving strategies.
+ *
+ * If the stream is long-lived, like ws, you should set the changed handler back
+ * to the default when the transaction wanting it is completed.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_ss_change_handlers(struct lws_ss_handle *h, lws_sscb_rx rx, lws_sscb_tx tx,
+ lws_sscb_state state);
/**
* lws_ss_add_peer_tx_credit() - allow peer to transmit more to us
*/
LWS_VISIBLE LWS_EXTERN int
lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h);
+
+LWS_VISIBLE LWS_EXTERN const char *
+lws_ss_tag(struct lws_ss_handle *h);
+
+
+#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
+/**
+ * lws_ss_sigv4_set_aws_key() - set aws credential into system blob
+ *
+ * \param context: lws_context
+ * \param idx: the system blob index specified in the policy, currently
+ * up to 4 blobs.
+ * \param keyid: aws access keyid
+ * \param key: aws access key
+ *
+ * Return 0 if OK or nonzero if e.g. idx is invalid; system blob heap appending
+ * fails.
+ */
+
+LWS_VISIBLE LWS_EXTERN int
+lws_ss_sigv4_set_aws_key(struct lws_context* context, uint8_t idx,
+ const char * keyid, const char * key);
+
+/**
+ * lws_aws_filesystem_credentials_helper() - read aws credentials from file
+ *
+ * \param path: path to read, ~ at start is converted to $HOME contents if any
+ * \param kid: eg, "aws_access_key_id"
+ * \param ak: eg, "aws_secret_access_key"
+ * \param aws_keyid: pointer to pointer for allocated keyid from credentials file
+ * \param aws_key: pointer to pointer for allocated key from credentials file
+ *
+ * Return 0 if both *aws_keyid and *aws_key allocated from the config file, else
+ * nonzero, and neither *aws_keyid or *aws_key are allocated.
+ *
+ * If *aws_keyid and *aws_key are set, it's the user's responsibility to
+ * free() them when they are no longer needed.
+ */
+
+LWS_VISIBLE LWS_EXTERN int
+lws_aws_filesystem_credentials_helper(const char *path, const char *kid,
+ const char *ak, char **aws_keyid,
+ char **aws_key);
+
+#endif
+
+///@}
+
lws_seq_event_cb cb; /* seq callback */
const char *name; /* seq name */
const lws_retry_bo_t *retry; /* retry policy */
+ uint8_t wakesuspend:1; /* important enough to
+ * wake system */
} lws_seq_info_t;
/**
* APIs specific to libuv event loop itegration
*/
///@{
-#ifdef LWS_WITH_LIBUV
+#if defined(LWS_WITH_LIBUV) && defined(UV_ERRNO_MAP)
+
/*
* Any direct libuv allocations in lws protocol handlers must participate in the
* lws reference counting scheme. Two apis are provided:
*
- * - lws_libuv_static_refcount_add(handle, context) to mark the handle with
+ * - lws_libuv_static_refcount_add(handle, context, tsi) to mark the handle with
* a pointer to the context and increment the global uv object counter
*
* - lws_libuv_static_refcount_del() which should be used as the close callback
lws_uv_getloop(struct lws_context *context, int tsi);
LWS_VISIBLE LWS_EXTERN void
-lws_libuv_static_refcount_add(uv_handle_t *, struct lws_context *context);
+lws_libuv_static_refcount_add(uv_handle_t *, struct lws_context *context,
+ int tsi);
LWS_VISIBLE LWS_EXTERN void
lws_libuv_static_refcount_del(uv_handle_t *);
#endif /* LWS_WITH_LIBUV */
#if defined(LWS_PLAT_FREERTOS)
-#define lws_libuv_static_refcount_add(_a, _b)
+#define lws_libuv_static_refcount_add(_a, _b, _c)
#define lws_libuv_static_refcount_del NULL
#endif
///@}
--- /dev/null
+/*
+ * Generic Settings storage
+ *
+ * Copyright (C) 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ *
+ * This is like an abstract class for non-volatile storage, whether in a file-
+ * system or flash-backed blocks, etc. Named blobs of variable size are stored
+ * in nonvolatile media of some sort. Typically, these are JSON objects under
+ * a naming scheme like, eg, "network".
+ *
+ * There's a platform-specific storage identifier opaque_plat provided when the
+ * storage object is instantiated, this describes eg the storage device or
+ * partition in instantiation-specific terms.
+ *
+ * Blobs have a further "filename" associated with them.
+ */
+
+#define LSOOPEN_FLAG_WRITEABLE (1 << 0)
+
+struct lws_settings_ops;
+
+typedef struct {
+ void *handle_plat;
+ const struct lws_settings_ops *so;
+ uint8_t refcount;
+ void *opaque_plat;
+} lws_settings_instance_t;
+
+typedef struct lws_settings_ops {
+ int (*get)(lws_settings_instance_t *si, const char *name,
+ uint8_t *dest, size_t *max_actual);
+ /**< if dest is NULL, max_actual is set to the actual length without
+ * copying anything out */
+ int (*set)(lws_settings_instance_t *si, const char *name,
+ const uint8_t *src, size_t len);
+} lws_settings_ops_t;
+
+/**
+ * lws_settings_plat_get() - read a named blob from a settings instance
+ *
+ * \param si: the settings instance
+ * \param name: the name of the setting blob in the instance
+ * \param dest: NULL, or the buffer to copy the setting blob info
+ * \param max_actual: point to size of dest, or zero; actual blob size on exit
+ *
+ * If the named blob doesn't exist in the si, or can't read, returns nonzero.
+ * Otherwise, returns 0 and sets *max_actual to the true blob size. If dest is
+ * non-NULL, as much of the blob as will fit in the amount specified by
+ * *max_actual on entry is copied to dest.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_settings_plat_get(lws_settings_instance_t *si, const char *name,
+ uint8_t *dest, size_t *max_actual);
+
+/**
+ * lws_settings_plat_get() - read a named blob from a settings instance
+ *
+ * \param si: the settings instance
+ * \param name: the name of the setting blob in the instance
+ * \param src: blob to copy to settings instance
+ * \param len: length of blob to copy
+ *
+ * Creates or replaces a settings blob of the given name made up of the \p len
+ * bytes of data from \p src.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_settings_plat_set(lws_settings_instance_t *si, const char *name,
+ const uint8_t *src, size_t len);
+
+/**
+ * lws_settings_plat_printf() - read a named blob from a settings instance
+ *
+ * \param si: the settings instance
+ * \param name: the name of the setting blob in the instance
+ * \param format: printf-style format string
+ *
+ * Creates or replaces a settings blob of the given name from the printf-style
+ * format string and arguments provided. There's no specific limit to the size,
+ * the size is computed and then a temp heap buffer used.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_settings_plat_printf(lws_settings_instance_t *si, const char *name,
+ const char *format, ...) LWS_FORMAT(3);
+
+#define lws_settings_ops_plat \
+ .get = lws_settings_plat_get, \
+ .set = lws_settings_plat_set,
+
+LWS_VISIBLE LWS_EXTERN lws_settings_instance_t *
+lws_settings_init(const lws_settings_ops_t *so, void *opaque_plat);
+
+LWS_VISIBLE LWS_EXTERN void
+lws_settings_deinit(lws_settings_instance_t **si);
--- /dev/null
+/*
+ * lws System Message Distribution
+ *
+ * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ */
+
+#define LWS_SMD_MAX_PAYLOAD 384
+#define LWS_SMD_CLASS_BITFIELD_BYTES 4
+
+#define LWS_SMD_STREAMTYPENAME "_lws_smd"
+#define LWS_SMD_SS_RX_HEADER_LEN 16
+
+typedef uint32_t lws_smd_class_t;
+
+struct lws_smd_msg; /* opaque */
+struct lws_smd_peer; /* opaque */
+
+/*
+ * Well-known device classes
+ */
+
+enum {
+ LWSSMDCL_INTERACTION = (1 << 0),
+ /**<
+ * Any kind of event indicating a user was interacting with the device,
+ * eg, press a button, touched the screen, lifted the device etc
+ */
+ LWSSMDCL_SYSTEM_STATE = (1 << 1),
+ /**<
+ * The lws_system state changed, eg, to OPERATIONAL
+ */
+ LWSSMDCL_NETWORK = (1 << 2),
+ /**<
+ * Something happened on the network, eg, link-up or DHCP, or captive
+ * portal state update
+ */
+ LWSSMDCL_METRICS = (1 << 3),
+ /**<
+ * An SS client process is reporting a metric to the proxy (this class
+ * is special in that it is not rebroadcast by the proxy)
+ */
+
+ LWSSMDCL_USER_BASE_BITNUM = 24
+};
+
+/**
+ * lws_smd_msg_alloc() - allocate a message of length len
+ *
+ * \param ctx: the lws_context
+ * \param _class: the smd message class, recipients filter on this
+ * \param len: the required payload length
+ *
+ * This helper returns an opaque lws_smd_msg pointer and sets *buf to a buffer
+ * associated with it of length \p len.
+ *
+ * In this way the lws_msg_smd type remains completely opaque and the allocated
+ * area can be prepared by the caller directly, without copying.
+ *
+ * On failure, it returns NULL... it may fail for OOM but it may also fail if
+ * you request to allocate for a message class that the system has no
+ * participant who is listening for that class of event currently... the event
+ * generation action at the caller should be bypassed without error then.
+ *
+ * This is useful if you have a message you know the length of. For text-based
+ * messages like JSON, lws_smd_msg_printf() is more convenient.
+ */
+LWS_VISIBLE LWS_EXTERN void * /* payload */
+lws_smd_msg_alloc(struct lws_context *ctx, lws_smd_class_t _class, size_t len);
+
+/**
+ * lws_smd_msg_free() - abandon a previously allocated message before sending
+ *
+ * \param payload: pointer the previously-allocated message payload
+ *
+ * Destroys a previously-allocated opaque message object and the requested
+ * buffer space, in the case that between allocating it and sending it, some
+ * condition was met that means it can no longer be sent, eg, an error
+ * generating the content. Otherwise there is no need to destroy allocated
+ * message objects with this, lws will take care of it.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_smd_msg_free(void **payload);
+
+/**
+ * lws_smd_msg_send() - queue a previously allocated message
+ *
+ * \param ctx: the lws_context
+ * \param msg: the prepared message
+ *
+ * Queues an allocated, prepared message for delivery to smd clients
+ *
+ * This is threadsafe to call from a non-service thread.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_smd_msg_send(struct lws_context *ctx, void *payload);
+
+/**
+ * lws_smd_msg_printf() - queue a previously allocated message
+ *
+ * \param ctx: the lws_context
+ * \param _class: the message class
+ * \param format: the format string to prepare the payload with
+ * \param ...: arguments for the format string, if any
+ *
+ * For string-based messages, eg, JSON, allows formatted creating of the payload
+ * size discovery, allocation and message send all in one step.
+ *
+ * Unlike lws_smd_msg_alloc() you do not need to know the length beforehand as
+ * this computes it and calls lws_smd_msg_alloc() with the correct length.
+ *
+ * To be clear this also calls through to lws_smd_msg_send(), it really does
+ * everything in one step. If there are no registered participants that want
+ * messages of \p _class, this function returns immediately without doing any
+ * allocation or anything else.
+ *
+ * This is threadsafe to call from a non-service thread.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_smd_msg_printf(struct lws_context *ctx, lws_smd_class_t _class,
+ const char *format, ...) LWS_FORMAT(3);
+
+/**
+ * lws_smd_ss_msg_printf() - helper to prepare smd ss message tx
+ *
+ * \param h: the ss handle
+ * \param buf: the ss tx buffer
+ * \param len: on entry, points to the ss tx buffer length, on exit, set to used
+ * \param _class: the message class
+ * \param format: the format string to prepare the payload with
+ * \param ...: arguments for the format string, if any
+ *
+ * This helper lets you produce SMD messages on an SS link of the builtin
+ * streamtype LWS_SMD_STREAMTYPENAME, using the same api format as
+ * lws_smd_msg_prinf(), but writing the message into the ss tx buffer from
+ * its tx() callback.
+ */
+
+struct lws_ss_handle;
+LWS_VISIBLE LWS_EXTERN int
+lws_smd_ss_msg_printf(const char *tag, uint8_t *buf, size_t *len,
+ lws_smd_class_t _class, const char *format, ...)
+ LWS_FORMAT(5);
+
+/**
+ * lws_smd_ss_rx_forward() - helper to forward smd messages that came in by SS
+ *
+ * \param ss_user: ss user pointer, as delivered to rx callback
+ * \param buf: the ss rx buffer
+ * \param len: the length of the ss rx buffer
+ *
+ * Proxied Secure Streams with the streamtype LWS_SMD_STREAMTYPENAME receive
+ * serialized SMD messages from the proxy, this helper allows them to be
+ * translated into deserialized SMD messages and forwarded to registered SMD
+ * participants in the local context in one step.
+ *
+ * Just pass through what arrived in the LWS_SMD_STREAMTYPENAME rx() callback
+ * to this api.
+ *
+ * Returns 0 if OK else nonzero if unable to queue the SMD message.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_smd_ss_rx_forward(void *ss_user, const uint8_t *buf, size_t len);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_smd_sspc_rx_forward(void *ss_user, const uint8_t *buf, size_t len);
+
+typedef int (*lws_smd_notification_cb_t)(void *opaque, lws_smd_class_t _class,
+ lws_usec_t timestamp, void *buf,
+ size_t len);
+
+#define LWSSMDREG_FLAG_PROXIED_SS (1 << 0)
+/**< It's actually a proxied SS connection registering, opaque is the ss h */
+
+/*
+ * lws_smd_register() - register to receive smd messages
+ *
+ * \param ctx: the lws_context
+ * \param opaque: an opaque pointer handed to the callback
+ * \param flags: typically 0
+ * \param _class_filter: bitmap of message classes we care about
+ * \param cb: the callback to receive messages
+ *
+ * Queues an allocated, prepared message for delivery to smd clients.
+ *
+ * Returns NULL on failure, or an opaque handle which may be given to
+ * lws_smd_unregister() to stop participating in the shared message queue.
+ *
+ * This is threadsafe to call from a non-service thread.
+ */
+
+LWS_VISIBLE LWS_EXTERN struct lws_smd_peer *
+lws_smd_register(struct lws_context *ctx, void *opaque, int flags,
+ lws_smd_class_t _class_filter, lws_smd_notification_cb_t cb);
+
+/*
+ * lws_smd_unregister() - unregister receiving smd messages
+ *
+ * \param pr: the handle returned from the registration
+ *
+ * Destroys the registration of the callback for messages and ability to send
+ * messages.
+ *
+ * It's not necessary to call this if the registration wants to survive for as
+ * long as the lws_context... lws_context_destroy will also clean up any
+ * registrations still active by then.
+ */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_smd_unregister(struct lws_smd_peer *pr);
--- /dev/null
+/*
+ * Generic I2C ops
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ *
+ * This is like an abstract class for spi, a real implementation provides
+ * functions for the ops that use the underlying OS arrangements.
+ *
+ * It uses descriptor / queuing semantics but eg the GPIO BB implementantion is
+ * synchronous.
+ */
+
+#if !defined(__LWS_SPI_H__)
+#define __LWS_SPI_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef int (*lws_spi_cb_t)(void *opaque);
+
+enum {
+ LWSSPIMODE_CPOL = (1 << 0),
+ LWSSPIMODE_CPHA = (1 << 1),
+
+ LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_RISING = 0,
+ LWS_SPI_BUSMODE_CLK_IDLE_HIGH_SAMP_RISING = LWSSPIMODE_CPOL,
+ LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_FALLING = LWSSPIMODE_CPHA,
+ LWS_SPI_BUSMODE_CLK_IDLE_HIGH_SAMP_FALLING = LWSSPIMODE_CPHA |
+ LWSSPIMODE_CPOL,
+
+ LWS_SPI_TXN_HALF_DUPLEX_DISCRETE = 0,
+ /**< separate MISO and MOSI, but only either MISO or MOSI has data at
+ * one time... i2c style in SPI */
+};
+
+typedef struct lws_spi_desc {
+ const uint8_t *src;
+ const uint8_t *data;
+ uint8_t *dest;
+ void *opaque;
+ lws_spi_cb_t completion_cb;
+ uint16_t count_cmd;
+ uint16_t count_write;
+ uint16_t count_read;
+ uint8_t txn_type;
+ uint8_t channel;
+} lws_spi_desc_t;
+
+typedef struct lws_spi_ops {
+ int (*init)(const struct lws_spi_ops *ctx);
+ int (*queue)(const struct lws_spi_ops *ctx, const lws_spi_desc_t *desc);
+ uint8_t bus_mode;
+} lws_spi_ops_t;
+
+#endif
--- /dev/null
+/*
+ * lws abstract display implementation for ssd1306 on i2c
+ *
+ * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ */
+
+#if !defined(__LWS_DISPLAY_SSD1306_I2C_H__)
+#define __LWS_DISPLAY_SSD1306_I2C_H__
+
+/*
+ * D/C# pin on SSD1306 sets the I2C device ads
+ * from these two options (7-bit address)
+ */
+
+#define SSD1306_I2C7_ADS1 0x3c
+#define SSD1306_I2C7_ADS2 0x3d
+
+typedef struct lws_display_ssd1306 {
+
+ lws_display_t disp; /* use lws_display_ssd1306_ops to set ops */
+ const lws_i2c_ops_t *i2c; /* i2c ops */
+
+ const lws_gpio_ops_t *gpio; /* NULL or gpio ops */
+ _lws_plat_gpio_t reset_gpio; /* if gpio ops, nReset gpio # */
+
+ uint8_t i2c7_address; /* one of SSD1306_I2C7_ADS... */
+
+} lws_display_ssd1306_t;
+
+int
+lws_display_ssd1306_i2c_init(const struct lws_display *disp);
+int
+lws_display_ssd1306_i2c_contrast(const struct lws_display *disp, uint8_t b);
+int
+lws_display_ssd1306_i2c_blit(const struct lws_display *disp, const uint8_t *src,
+ lws_display_scalar x, lws_display_scalar y,
+ lws_display_scalar w, lws_display_scalar h);
+int
+lws_display_ssd1306_i2c_power(const struct lws_display *disp, int state);
+
+#define lws_display_ssd1306_ops \
+ .init = lws_display_ssd1306_i2c_init, \
+ .contrast = lws_display_ssd1306_i2c_contrast, \
+ .blit = lws_display_ssd1306_i2c_blit, \
+ .power = lws_display_ssd1306_i2c_power
+#endif
struct lws_state_notify_link;
struct lws_state_manager;
+#if defined(LWS_WITH_SYS_STATE)
+
typedef int (*lws_state_notify_t)(struct lws_state_manager *mgr,
struct lws_state_notify_link *link,
int current, int target);
typedef struct lws_state_manager {
lws_dll2_owner_t notify_list;
+ struct lws_context *context;
void *parent;
+#if defined(LWS_WITH_SYS_SMD)
+ lws_smd_class_t smd_class;
+#endif
/**< optional opaque pointer to owning object... useful to make such
* a pointer available to a notification callback. Ignored by lws */
- const char **state_names; /* may be NULL */
+ const char **state_names;
const char *name;
int state;
} lws_state_manager_t;
*/
LWS_EXTERN LWS_VISIBLE int
lws_state_transition(lws_state_manager_t *mgr, int target);
+
+#else
+
+#endif
+++ /dev/null
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
- *
- * 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.
- */
-
-/*
- * Stats are all uint64_t numbers that start at 0.
- * Index names here have the convention
- *
- * _C_ counter
- * _B_ byte count
- * _MS_ millisecond count
- */
-
-enum {
- LWSSTATS_C_CONNECTIONS, /**< count incoming connections */
- LWSSTATS_C_API_CLOSE, /**< count calls to close api */
- LWSSTATS_C_API_READ, /**< count calls to read from socket api */
- LWSSTATS_C_API_LWS_WRITE, /**< count calls to lws_write API */
- LWSSTATS_C_API_WRITE, /**< count calls to write API */
- LWSSTATS_C_WRITE_PARTIALS, /**< count of partial writes */
- LWSSTATS_C_WRITEABLE_CB_REQ, /**< count of writable callback requests */
- LWSSTATS_C_WRITEABLE_CB_EFF_REQ, /**< count of effective writable callback requests */
- LWSSTATS_C_WRITEABLE_CB, /**< count of writable callbacks */
- LWSSTATS_C_SSL_CONNECTIONS_FAILED, /**< count of failed SSL connections */
- LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, /**< count of accepted SSL connections */
- LWSSTATS_C_SSL_ACCEPT_SPIN, /**< count of SSL_accept() attempts */
- LWSSTATS_C_SSL_CONNS_HAD_RX, /**< count of accepted SSL conns that have had some RX */
- LWSSTATS_C_TIMEOUTS, /**< count of timed-out connections */
- LWSSTATS_C_SERVICE_ENTRY, /**< count of entries to lws service loop */
- LWSSTATS_B_READ, /**< aggregate bytes read */
- LWSSTATS_B_WRITE, /**< aggregate bytes written */
- LWSSTATS_B_PARTIALS_ACCEPTED_PARTS, /**< aggreate of size of accepted write data from new partials */
- LWSSTATS_US_SSL_ACCEPT_LATENCY_AVG, /**< aggregate delay in accepting connection */
- LWSSTATS_US_WRITABLE_DELAY_AVG, /**< aggregate delay between asking for writable and getting cb */
- LWSSTATS_US_WORST_WRITABLE_DELAY, /**< single worst delay between asking for writable and getting cb */
- LWSSTATS_US_SSL_RX_DELAY_AVG, /**< aggregate delay between ssl accept complete and first RX */
- LWSSTATS_C_PEER_LIMIT_AH_DENIED, /**< number of times we would have given an ah but for the peer limit */
- LWSSTATS_C_PEER_LIMIT_WSI_DENIED, /**< number of times we would have given a wsi but for the peer limit */
- LWSSTATS_C_CONNS_CLIENT, /**< attempted client conns */
- LWSSTATS_C_CONNS_CLIENT_FAILED, /**< failed client conns */
-
- /* Add new things just above here ---^
- * This is part of the ABI, don't needlessly break compatibility
- *
- * UPDATE stat_names in stats.c in sync with this!
- */
- LWSSTATS_SIZE
-};
-
-#if defined(LWS_WITH_STATS)
-
-LWS_VISIBLE LWS_EXTERN uint64_t
-lws_stats_get(struct lws_context *context, int index);
-LWS_VISIBLE LWS_EXTERN void
-lws_stats_log_dump(struct lws_context *context);
-#else
-static LWS_INLINE uint64_t
-lws_stats_get(struct lws_context *context, int index) { (void)context; (void)index; return 0; }
-static LWS_INLINE void
-lws_stats_log_dump(struct lws_context *context) { (void)context; }
-#endif
LSMT_LIST,
LSMT_CHILD_PTR,
LSMT_SCHEMA,
+ LSMT_BLOB_PTR,
} lws_struct_map_type_eum;
LSMT_SCHEMA \
}
+/*
+ * This is just used to create the table schema, it is not part of serialization
+ * and deserialization. Blobs should be accessed separately.
+ */
+
+#define LSM_BLOB_PTR(type, blobptr_name, qname) \
+ { \
+ qname, /* JSON item, or sqlite3 column name */ \
+ NULL, \
+ NULL, \
+ offsetof(type, blobptr_name), /* member that points to blob */ \
+ sizeof (((type *)0)->blobptr_name), /* size of blob pointer */ \
+ 0, /* member holding blob len */ \
+ 0, /* size of blob length member */ \
+ LSMT_BLOB_PTR \
+ }
+
typedef struct lws_struct_serialize_st {
const struct lws_dll2 *dllpos;
const lws_struct_map_t *map;
} lws_struct_serialize_st_t;
enum {
- LSSERJ_FLAG_PRETTY = 1
+ LSSERJ_FLAG_PRETTY = (1 << 0),
+ LSSERJ_FLAG_OMIT_SCHEMA = (1 << 1)
};
typedef struct lws_struct_serialize {
lws_struct_json_serialize(lws_struct_serialize_t *js, uint8_t *buf,
size_t len, size_t *written);
-#if defined(LWS_WITH_STRUCT_SQLITE3)
+typedef struct sqlite3 sqlite3;
LWS_VISIBLE LWS_EXTERN int
lws_struct_sq3_serialize(sqlite3 *pdb, const lws_struct_map_t *schema,
LWS_VISIBLE LWS_EXTERN int
lws_struct_sq3_open(struct lws_context *context, const char *sqlite3_path,
- sqlite3 **pdb);
+ char create_if_missing, sqlite3 **pdb);
LWS_VISIBLE LWS_EXTERN int
lws_struct_sq3_close(sqlite3 **pdb);
-#endif
/*
* libwebsockets - small server side websockets and web server implementation
*
- * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
LWS_SYSBLOB_TYPE_DEVICE_FW_VERSION,
LWS_SYSBLOB_TYPE_DEVICE_TYPE,
LWS_SYSBLOB_TYPE_NTP_SERVER,
+ LWS_SYSBLOB_TYPE_MQTT_CLIENT_ID,
+ LWS_SYSBLOB_TYPE_MQTT_USERNAME,
+ LWS_SYSBLOB_TYPE_MQTT_PASSWORD,
+
+#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
+ /* extend 4 more auth blobs, each has 2 slots */
+ LWS_SYSBLOB_TYPE_EXT_AUTH1,
+ LWS_SYSBLOB_TYPE_EXT_AUTH2 = LWS_SYSBLOB_TYPE_EXT_AUTH1 + 2,
+ LWS_SYSBLOB_TYPE_EXT_AUTH3 = LWS_SYSBLOB_TYPE_EXT_AUTH2 + 2,
+ LWS_SYSBLOB_TYPE_EXT_AUTH4 = LWS_SYSBLOB_TYPE_EXT_AUTH3 + 2,
+ LWS_SYSBLOB_TYPE_EXT_AUTH4_1,
+#endif
LWS_SYSBLOB_TYPE_COUNT /* ... always last */
} lws_system_blob_item_t;
* can operate normally */
LWS_SYSTATE_IFACE_COLDPLUG, /* existing net ifaces iterated */
LWS_SYSTATE_DHCP, /* at least one net iface configured */
+ LWS_SYSTATE_CPD_PRE_TIME, /* Captive portal detect without valid
+ * time, good for non-https tests... if
+ * you care about it, implement and
+ * call lws_system_ops_t
+ * .captive_portal_detect_request()
+ * and move the state forward according
+ * to the result. */
LWS_SYSTATE_TIME_VALID, /* ntpclient ran, or hw time valid...
* tls cannot work until we reach here
*/
+ LWS_SYSTATE_CPD_POST_TIME, /* Captive portal detect after time was
+ * time, good for https tests... if
+ * you care about it, implement and
+ * call lws_system_ops_t
+ * .captive_portal_detect_request()
+ * and move the state forward according
+ * to the result. */
+
LWS_SYSTATE_POLICY_VALID, /* user code knows how to operate... */
LWS_SYSTATE_REGISTERED, /* device has an identity... */
LWS_SYSTATE_AUTH1, /* identity used for main auth token */
* LWS_SYSTATE_POLICY_VALID */
} lws_system_states_t;
+/* Captive Portal Detect -related */
+
+typedef enum {
+ LWS_CPD_UNKNOWN = 0, /* test didn't happen ince last DHCP acq yet */
+ LWS_CPD_INTERNET_OK, /* no captive portal: our CPD test passed OK,
+ * we can go out on the internet */
+ LWS_CPD_CAPTIVE_PORTAL, /* we inferred we're behind a captive portal */
+ LWS_CPD_NO_INTERNET, /* we couldn't touch anything */
+} lws_cpd_result_t;
typedef void (*lws_attach_cb_t)(struct lws_context *context, int tsi, void *opaque);
struct lws_attach_item;
* __lws_system_attach() is provided to do the actual work inside the
* system-specific locking.
*/
+ int (*captive_portal_detect_request)(struct lws_context *context);
+ /**< Check if we can go out on the internet cleanly, or if we are being
+ * redirected or intercepted by a captive portal.
+ * Start the check that proceeds asynchronously, and report the results
+ * by calling lws_captive_portal_detect_result() api
+ */
+
+ int (*metric_report)(lws_metric_pub_t *mdata);
+ /**< metric \p item is reporting an event of kind \p rpt,
+ * held in \p mdata... return 0 to leave the metric object as it is,
+ * or nonzero to reset it. */
+
+ uint32_t wake_latency_us;
+ /**< time taken for this device to wake from suspend, in us
+ */
} lws_system_ops_t;
+#if defined(LWS_WITH_SYS_STATE)
+
/**
* lws_system_get_state_manager() - return the state mgr object for system state
*
LWS_EXTERN LWS_VISIBLE lws_state_manager_t *
lws_system_get_state_manager(struct lws_context *context);
-
+#endif
/* wrappers handle NULL members or no ops struct set at all cleanly */
LWS_EXTERN LWS_VISIBLE const lws_system_ops_t *
lws_system_get_ops(struct lws_context *context);
+#if defined(LWS_WITH_SYS_STATE)
+
/**
* lws_system_context_from_system_mgr() - return context from system state mgr
*
LWS_EXTERN LWS_VISIBLE struct lws_context *
lws_system_context_from_system_mgr(lws_state_manager_t *mgr);
+#endif
/**
* __lws_system_attach() - get and set items on context attach list
struct lws_attach_item **get);
-typedef int (*dhcpc_cb_t)(void *opaque, int af, uint8_t *ip, int ip_len);
+enum {
+ LWSDH_IPV4_SUBNET_MASK = 0,
+ LWSDH_IPV4_BROADCAST,
+ LWSDH_LEASE_SECS,
+ LWSDH_REBINDING_SECS,
+ LWSDH_RENEWAL_SECS,
+
+ _LWSDH_NUMS_COUNT,
+
+ LWSDH_SA46_IP = 0,
+ LWSDH_SA46_DNS_SRV_1,
+ LWSDH_SA46_DNS_SRV_2,
+ LWSDH_SA46_DNS_SRV_3,
+ LWSDH_SA46_DNS_SRV_4,
+ LWSDH_SA46_IPV4_ROUTER,
+ LWSDH_SA46_NTP_SERVER,
+ LWSDH_SA46_DHCP_SERVER,
+
+ _LWSDH_SA46_COUNT,
+};
+
+typedef struct lws_dhcpc_ifstate {
+ char ifname[16];
+ char domain[64];
+ uint8_t mac[6];
+ uint32_t nums[_LWSDH_NUMS_COUNT];
+ lws_sockaddr46 sa46[_LWSDH_SA46_COUNT];
+} lws_dhcpc_ifstate_t;
+
+typedef int (*dhcpc_cb_t)(void *opaque, lws_dhcpc_ifstate_t *is);
/**
* lws_dhcpc_request() - add a network interface to dhcpc management
* Register a network interface as being managed by DHCP. lws will proceed to
* try to acquire an IP. Requires LWS_WITH_SYS_DHCP_CLIENT at cmake.
*/
-int
+LWS_EXTERN LWS_VISIBLE int
lws_dhcpc_request(struct lws_context *c, const char *i, int af, dhcpc_cb_t cb,
void *opaque);
*
* Remove handling of the network interface from dhcp.
*/
-int
+LWS_EXTERN LWS_VISIBLE int
lws_dhcpc_remove(struct lws_context *context, const char *iface);
/**
* Returns 1 if any network interface managed by dhcpc has reached the BOUND
* state (has acquired an IP, gateway and DNS server), otherwise 0.
*/
-int
+LWS_EXTERN LWS_VISIBLE int
lws_dhcpc_status(struct lws_context *context, lws_sockaddr46 *sa46);
+
+/**
+ * lws_system_cpd_start() - helper to initiate captive portal detection
+ *
+ * \param context: the lws_context
+ *
+ * Resets the context's captive portal state to LWS_CPD_UNKNOWN and calls the
+ * lws_system_ops_t captive_portal_detect_request() implementation to begin
+ * testing the captive portal state.
+ */
+LWS_EXTERN LWS_VISIBLE int
+lws_system_cpd_start(struct lws_context *context);
+
+LWS_EXTERN LWS_VISIBLE void
+lws_system_cpd_start_defer(struct lws_context *cx, lws_usec_t defer_us);
+
+
+/**
+ * lws_system_cpd_set() - report the result of the captive portal detection
+ *
+ * \param context: the lws_context
+ * \param result: one of the LWS_CPD_ constants representing captive portal state
+ *
+ * Sets the context's captive portal detection state to result. User captive
+ * portal detection code would call this once it had a result from its test.
+ */
+LWS_EXTERN LWS_VISIBLE void
+lws_system_cpd_set(struct lws_context *context, lws_cpd_result_t result);
+
+
+/**
+ * lws_system_cpd_state_get() - returns the last tested captive portal state
+ *
+ * \param context: the lws_context
+ *
+ * Returns one of the LWS_CPD_ constants indicating the system's understanding
+ * of the current captive portal situation.
+ */
+LWS_EXTERN LWS_VISIBLE lws_cpd_result_t
+lws_system_cpd_state_get(struct lws_context *context);
/*
* libwebsockets - small server side websockets and web server implementation
*
- * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
};
struct lws_threadpool_task_args {
- struct lws *wsi; /**< user must set to wsi task is bound to */
+#if defined(LWS_WITH_SECURE_STREAMS)
+ struct lws_ss_handle *ss; /**< either wsi or ss must be set */
+#endif
+ struct lws *wsi; /**< either wsi or ss must be set */
+
void *user; /**< user may set (user-private pointer) */
const char *name; /**< user may set to describe task */
char async_task; /**< set to allow the task to shrug off the loss
* This doesn't free the task. It only shortcuts it to state
* LWS_TP_STATUS_STOPPED. lws_threadpool_task_status() must be performed on
* the task separately once it is in LWS_TP_STATUS_STOPPED to free the task.
+ *
+ * DEPRECATED: You should use lws_threadpool_dequeue_task() with
+ * lws_threadpool_get_task_wsi() / _ss() if you know there can only be one task
+ * per connection, or call it via lws_threadpool_foreach_task_wsi() / _ss() to
+ * get the tasks bound to the connection.
*/
LWS_VISIBLE LWS_EXTERN int
-lws_threadpool_dequeue(struct lws *wsi);
+lws_threadpool_dequeue(struct lws *wsi) LWS_WARN_DEPRECATED;
+
+LWS_VISIBLE LWS_EXTERN int
+lws_threadpool_dequeue_task(struct lws_threadpool_task *task);
+
/**
- * lws_threadpool_task_status() - Dequeue or try to stop a running task
+ * lws_threadpool_task_status() - reap completed tasks
*
* \param wsi: the wsi to query the current task of
* \param task: receives a pointer to the opaque task
*
* Its use is to make sure the service thread has seen the state of the task
* before deleting it.
+ *
+ * DEPRECATED... use lws_threadpool_task_status() instead and get the task
+ * pointer from lws_threadpool_get_task_wsi() / _ss() if you know there can only
+ * be one, else call it via lws_threadpool_foreach_task_wsi() / _ss()
*/
LWS_VISIBLE LWS_EXTERN enum lws_threadpool_task_status
lws_threadpool_task_status_wsi(struct lws *wsi,
- struct lws_threadpool_task **task, void **user);
+ struct lws_threadpool_task **task, void **user)
+ LWS_WARN_DEPRECATED;
+
+LWS_VISIBLE LWS_EXTERN enum lws_threadpool_task_status
+lws_threadpool_task_status(struct lws_threadpool_task *task, void **user);
+
+LWS_VISIBLE LWS_EXTERN enum lws_threadpool_task_status
+lws_threadpool_task_status_noreap(struct lws_threadpool_task *task);
/**
* lws_threadpool_task_sync() - Indicate to a stalled task it may continue
LWS_VISIBLE LWS_EXTERN void
lws_threadpool_dump(struct lws_threadpool *tp);
+
+
+
+LWS_VISIBLE LWS_EXTERN struct lws_threadpool_task *
+lws_threadpool_get_task_wsi(struct lws *wsi);
+
+#if defined(LWS_WITH_SECURE_STREAMS)
+LWS_VISIBLE LWS_EXTERN struct lws_threadpool_task *
+lws_threadpool_get_task_ss(struct lws_ss_handle *ss);
+#endif
+
+
+LWS_VISIBLE LWS_EXTERN int
+lws_threadpool_foreach_task_wsi(struct lws *wsi, void *user,
+ int (*cb)(struct lws_threadpool_task *task,
+ void *user));
+
+#if defined(LWS_WITH_SECURE_STREAMS)
+LWS_VISIBLE LWS_EXTERN int
+lws_threadpool_foreach_task_ss(struct lws_ss_handle *ss, void *user,
+ int (*cb)(struct lws_threadpool_task *task, void *user));
+#endif
+
+
//@}
void
lws_set_timeout_us(struct lws *wsi, enum pending_timeout reason, lws_usec_t us);
+/* helper for clearer LWS_TO_KILL_ASYNC / LWS_TO_KILL_SYNC usage */
+#define lws_wsi_close(w, to_kill) lws_set_timeout(w, 1, to_kill)
+
+
#define LWS_SET_TIMER_USEC_CANCEL ((lws_usec_t)-1ll)
#define LWS_USEC_PER_SEC ((lws_usec_t)1000000)
LWS_VISIBLE LWS_EXTERN void
lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs);
+#if defined(LWS_WITH_DEPRECATED_THINGS)
+
/*
* lws_timed_callback_vh_protocol() - calls back a protocol on a vhost after
* the specified delay in seconds
* \param reason: callback reason
* \param secs: how many seconds in the future to do the callback.
*
+ * DEPRECATED since v4.1
+ *
* Callback the specified protocol with a fake wsi pointing to the specified
* vhost and protocol, with the specified reason, at the specified time in the
* future.
LWS_VISIBLE LWS_EXTERN int
lws_timed_callback_vh_protocol(struct lws_vhost *vh,
const struct lws_protocols *prot,
- int reason, int secs);
+ int reason, int secs)
+LWS_WARN_DEPRECATED;
/*
* lws_timed_callback_vh_protocol_us() - calls back a protocol on a vhost after
* \param reason: callback reason
* \param us: how many us in the future to do the callback.
*
+ * DEPRECATED since v4.1
+ *
* Callback the specified protocol with a fake wsi pointing to the specified
* vhost and protocol, with the specified reason, at the specified time in the
* future.
LWS_VISIBLE LWS_EXTERN int
lws_timed_callback_vh_protocol_us(struct lws_vhost *vh,
const struct lws_protocols *prot, int reason,
- lws_usec_t us);
+ lws_usec_t us)
+LWS_WARN_DEPRECATED;
+
+#endif
struct lws_sorted_usec_list;
typedef struct lws_sorted_usec_list {
struct lws_dll2 list; /* simplify the code by keeping this at start */
- sul_cb_t cb;
lws_usec_t us;
+ sul_cb_t cb;
+ uint32_t latency_us; /* us it may safely be delayed */
} lws_sorted_usec_list_t;
+/*
+ * There are multiple sul owners to allow accounting for, a) events that must
+ * wake from suspend, and b) events that can be missued due to suspend
+ */
+#define LWS_COUNT_PT_SUL_OWNERS 2
+
+#define LWSSULLI_MISS_IF_SUSPENDED 0
+#define LWSSULLI_WAKE_IF_SUSPENDED 1
/*
- * lws_sul_schedule() - schedule a callback
+ * lws_sul2_schedule() - schedule a callback
*
* \param context: the lws_context
* \param tsi: the thread service index (usually 0)
+ * \param flags: LWSSULLI_...
* \param sul: pointer to the sul element
- * \param cb: the scheduled callback
- * \param us: the delay before the callback arrives, or
- * LWS_SET_TIMER_USEC_CANCEL to cancel it.
*
* Generic callback-at-a-later time function. The callback happens on the
* event loop thread context.
*
* Although the api has us resultion, the actual resolution depends on the
- * platform and is commonly 1ms.
+ * platform and may be, eg, 1ms.
*
* This doesn't allocate and doesn't fail.
*
- * You can call it again with another us value to change the delay.
+ * If flags contains LWSSULLI_WAKE_IF_SUSPENDED, the scheduled event is placed
+ * on a sul owner list that, if the system has entered low power suspend mode,
+ * tries to arrange that the system should wake from platform suspend just
+ * before the event is due. Scheduled events without this flag will be missed
+ * in the case the system is in suspend and nothing else happens to have woken
+ * it.
+ *
+ * You can call it again with another us value to change the delay or move the
+ * event to a different owner (ie, wake or miss on suspend).
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_sul2_schedule(struct lws_context *context, int tsi, int flags,
+ lws_sorted_usec_list_t *sul);
+
+/*
+ * lws_sul_cancel() - cancel scheduled callback
+ *
+ * \param sul: pointer to the sul element
+ *
+ * If it's scheduled, remove the sul from its owning sorted list.
+ * If not scheduled, it's a NOP.
+ */
+LWS_VISIBLE LWS_EXTERN void
+lws_sul_cancel(lws_sorted_usec_list_t *sul);
+
+/*
+ * lws_sul_earliest_wakeable_event() - get earliest wake-from-suspend event
+ *
+ * \param ctx: the lws context
+ * \param pearliest: pointer to lws_usec_t to take the result
+ *
+ * Either returns 1 if no pending event, or 0 and sets *pearliest to the
+ * MONOTONIC time of the current earliest next expected event.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_sul_earliest_wakeable_event(struct lws_context *ctx, lws_usec_t *pearliest);
+
+/*
+ * For backwards compatibility
+ *
+ * If us is LWS_SET_TIMER_USEC_CANCEL, the sul is removed from the scheduler.
+ * New code can use lws_sul_cancel()
+ */
+
+LWS_VISIBLE LWS_EXTERN void
+lws_sul_schedule(struct lws_context *ctx, int tsi, lws_sorted_usec_list_t *sul,
+ sul_cb_t _cb, lws_usec_t _us);
+LWS_VISIBLE LWS_EXTERN void
+lws_sul_schedule_wakesuspend(struct lws_context *ctx, int tsi,
+ lws_sorted_usec_list_t *sul, sul_cb_t _cb,
+ lws_usec_t _us);
+
+#if defined(LWS_WITH_SUL_DEBUGGING)
+/**
+ * lws_sul_debug_zombies() - assert there are no scheduled sul in a given object
+ *
+ * \param ctx: lws_context
+ * \param po: pointer to the object that is about to be destroyed
+ * \param len: length of the object that is about to be destroyed
+ * \param destroy_description: string clue what any failure is related to
+ *
+ * This is an optional debugging helper that walks the sul scheduler lists
+ * confirming that there are no suls scheduled that live inside the object
+ * footprint described by po and len. When internal objects are about to be
+ * destroyed, like wsi / user_data or secure stream handles, if
+ * LWS_WITH_SUL_DEBUGGING is enabled the scheduler is checked for anything
+ * in the object being destroyed. If something found, an error is printed and
+ * an assert fired.
+ *
+ * Internal sul like timeouts should always be cleaned up correctly, but user
+ * suls in, eg, wsi user_data area, or in secure stream user allocation, may be
+ * the cause of difficult to find bugs if valgrind not available and the user
+ * code left a sul in the scheduler after destroying the object the sul was
+ * living in.
*/
LWS_VISIBLE LWS_EXTERN void
-lws_sul_schedule(struct lws_context *context, int tsi,
- lws_sorted_usec_list_t *sul, sul_cb_t cb, lws_usec_t us);
+lws_sul_debug_zombies(struct lws_context *ctx, void *po, size_t len,
+ const char *destroy_description);
+#else
+#define lws_sul_debug_zombies(_a, _b, _c, _d)
+#endif
/*
* lws_validity_confirmed() - reset the validity timer for a network connection
*/
LWS_VISIBLE LWS_EXTERN int
-__lws_sul_insert(lws_dll2_owner_t *own, lws_sorted_usec_list_t *sul,
- lws_usec_t us);
+__lws_sul_insert(lws_dll2_owner_t *own, lws_sorted_usec_list_t *sul);
LWS_VISIBLE LWS_EXTERN lws_usec_t
-__lws_sul_service_ripe(lws_dll2_owner_t *own, lws_usec_t usnow);
+__lws_sul_service_ripe(lws_dll2_owner_t *own, int own_len, lws_usec_t usnow);
///@}
--- /dev/null
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
+ *
+ * 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.
+ */
+
+/*! \defgroup tls_sessions TLS Session Management
+
+ APIs related to managing TLS Sessions
+*/
+//@{
+
+
+#define LWS_SESSION_TAG_LEN 96
+
+struct lws_tls_session_dump
+{
+ char tag[LWS_SESSION_TAG_LEN];
+ void *blob;
+ void *opaque;
+ size_t blob_len;
+};
+
+typedef int (*lws_tls_sess_cb_t)(struct lws_context *cx,
+ struct lws_tls_session_dump *info);
+
+/**
+ * lws_tls_session_dump_save() - serialize a tls session via a callback
+ *
+ * \param vh: the vhost to load into the session cache
+ * \param host: the name of the host the session relates to
+ * \param port: the port the session connects to on the host
+ * \param cb_save: the callback to perform the saving of the session blob
+ * \param opq: an opaque pointer passed into the callback
+ *
+ * If a session matching the vhost/host/port exists in the vhost's session
+ * cache, serialize it via the provided callback.
+ *
+ * \p opq is passed to the callback without being used by lws at all.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_tls_session_dump_save(struct lws_vhost *vh, const char *host, uint16_t port,
+ lws_tls_sess_cb_t cb_save, void *opq);
+
+/**
+ * lws_tls_session_dump_load() - deserialize a tls session via a callback
+ *
+ * \param vh: the vhost to load into the session cache
+ * \param host: the name of the host the session relates to
+ * \param port: the port the session connects to on the host
+ * \param cb_load: the callback to retreive the session blob from
+ * \param opq: an opaque pointer passed into the callback
+ *
+ * Try to preload a session described by the first three parameters into the
+ * client session cache, from the given callback.
+ *
+ * \p opq is passed to the callback without being used by lws at all.
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_tls_session_dump_load(struct lws_vhost *vh, const char *host, uint16_t port,
+ lws_tls_sess_cb_t cb_load, void *opq);
+
+///@}
#define LWS_TOKENIZE_F_HASH_COMMENT (1 << 7)
/* Do not treat / as a terminal character, so "multipart/related" is one token */
#define LWS_TOKENIZE_F_SLASH_NONTERM (1 << 8)
+/* Do not treat * as a terminal character, so "myfile*" is one token */
+#define LWS_TOKENIZE_F_ASTERISK_NONTERM (1 << 9)
+/* Do not treat = as a terminal character, so "x=y" is one token */
+#define LWS_TOKENIZE_F_EQUALS_NONTERM (1 << 10)
typedef enum {
* \p exp: the exp object to init
* \p priv: the user's object pointer to pass to callback
* \p cb: the callback to expand named objects
- * \p out: the start of the output buffer
+ * \p out: the start of the output buffer, or NULL just to get the length
* \p olen: the length of the output buffer in bytes
*
* Prepares an lws_strexp_t for use and sets the initial output buffer
+ *
+ * If \p out is NULL, substitution proceeds normally, but no output is produced,
+ * only the length is returned. olen should be set to the largest feasible
+ * overall length. To use this mode, the substitution callback must also check
+ * for NULL \p out and avoid producing the output.
*/
LWS_VISIBLE LWS_EXTERN void
lws_strexp_init(lws_strexp_t *exp, void *priv, lws_strexp_expand_cb cb,
* lws_strexp_reset_out() - reset the output buffer on an existing strexp
*
* \p exp: the exp object to init
- * \p out: the start of the output buffer
+ * \p out: the start of the output buffer, or NULL to just get length
* \p olen: the length of the output buffer in bytes
*
* Provides a new output buffer for lws_strexp_expand() to continue to write
* into. It can be the same as the old one if it has been copied out or used.
* The position of the next write will be reset to the start of the given buf.
+ *
+ * If \p out is NULL, substitution proceeds normally, but no output is produced,
+ * only the length is returned. \p olen should be set to the largest feasible
+ * overall length. To use this mode, the substitution callback must also check
+ * for NULL \p out and avoid producing the output.
*/
LWS_VISIBLE LWS_EXTERN void
lws_strexp_reset_out(lws_strexp_t *exp, char *out, size_t olen);
lws_strexp_expand(lws_strexp_t *exp, const char *in, size_t len,
size_t *pused_in, size_t *pused_out);
+/**
+ * lws_strcmp_wildcard() - strcmp but the first arg can have wildcards
+ *
+ * \p wildcard: a string that may contain zero to three *, and may lack a NUL
+ * \p len: length of the wildcard string
+ * \p check: string to test to see if it matches wildcard
+ *
+ * Exactly like strcmp, but supports patterns like "a*", "a*b", "a*b*" etc
+ * where a and b are arbitrary substrings
+ */
+LWS_VISIBLE LWS_EXTERN int
+lws_strcmp_wildcard(const char *wildcard, size_t len, const char *check);
* bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT
* are used.
*
- * This function provides the way to issue data back to the client
- * for both http and websocket protocols.
+ * This function provides the way to issue data back to the client, for any
+ * role (h1, h2, ws, raw, etc). It can only be called from the WRITEABLE
+ * callback.
*
* IMPORTANT NOTICE!
*
- * When sending with websocket protocol
+ * When sending with ws protocol
*
* LWS_WRITE_TEXT,
* LWS_WRITE_BINARY,
* LWS_WRITE_PING,
* LWS_WRITE_PONG,
*
- * or sending on http/2,
- *
- * the send buffer has to have LWS_PRE bytes valid BEFORE the buffer pointer you
- * pass to lws_write(). Since you'll probably want to use http/2 before too
- * long, it's wise to just always do this with lws_write buffers... LWS_PRE is
- * typically 16 bytes it's not going to hurt usually.
+ * or sending on http/2... the send buffer has to have LWS_PRE bytes valid
+ * BEFORE the buffer pointer you pass to lws_write(). Since you'll probably
+ * want to use http/2 before too long, it's wise to just always do this with
+ * lws_write buffers... LWS_PRE is typically 16 bytes it's not going to hurt
+ * usually.
*
* start of alloc ptr passed to lws_write end of allocation
* | | |
* [---------------- allocated memory ---------------]
* (for lws use) [====== user buffer ======]
*
- * This allows us to add protocol info before and after the data, and send as
- * one packet on the network without payload copying, for maximum efficiency.
+ * This allows us to add protocol info before the data, and send as one packet
+ * on the network without payload copying, for maximum efficiency.
*
* So for example you need this kind of code to use lws_write with a
* 128-byte payload
* // fill your part of the buffer... for example here it's all zeros
* memset(&buf[LWS_PRE], 0, 128);
*
- * lws_write(wsi, &buf[LWS_PRE], 128, LWS_WRITE_TEXT);
+ * if (lws_write(wsi, &buf[LWS_PRE], 128, LWS_WRITE_TEXT) < 128) {
+ * ... the connection is dead ...
+ * return -1;
+ * }
*
- * LWS_PRE is at least the frame nonce + 2 header + 8 length
- * LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left off.
- * The example apps no longer use it.
+ * LWS_PRE is currently 16, which covers ws and h2 frame headers, and is
+ * compatible with 32 and 64-bit alignment requirements.
*
- * Pad LWS_PRE to the CPU word size, so that word references
- * to the address immediately after the padding won't cause an unaligned access
- * error. Sometimes for performance reasons the recommended padding is even
- * larger than sizeof(void *).
+ * (LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left off.)
*
- * In the case of sending using websocket protocol, be sure to allocate
- * valid storage before and after buf as explained above. This scheme
- * allows maximum efficiency of sending data and protocol in a single
- * packet while not burdening the user code with any protocol knowledge.
+ * Return may be -1 is the write failed in a way indicating that the connection
+ * has ended already, in which case you can close your side, or a positive
+ * number that is at least the number of bytes requested to send (under some
+ * encapsulation scenarios, it can indicate more than you asked was sent).
*
- * Return may be -1 for a fatal error needing connection close, or the
- * number of bytes sent.
+ * The recommended test of the return is less than what you asked indicates
+ * the connection has failed.
*
* Truncated Writes
* ================
*
* LWS will buffer the remainder automatically, and send it out autonomously.
*
- * During that time, WRITABLE callbacks will be suppressed.
+ * During that time, WRITABLE callbacks to user code will be suppressed and
+ * instead used internally. After it completes, it will send an extra WRITEABLE
+ * callback to the user code, in case any request was missed. So it is possible
+ * to receive unasked-for WRITEABLE callbacks, the user code should have enough
+ * state to know if it wants to write anything and just return if not.
*
* This is to handle corner cases where unexpectedly the OS refuses what we
- * usually expect it to accept. You should try to send in chunks that are
- * almost always accepted in order to avoid the inefficiency of the buffering.
+ * usually expect it to accept. It's not recommended as the way to randomly
+ * send huge payloads, since it is being copied on to heap and is inefficient.
+ *
+ * Huge payloads should instead be sent in fragments that are around 2 x mtu,
+ * which is almost always directly accepted by the OS. To simplify this for
+ * ws fragments, there is a helper lws_write_ws_flags() below that simplifies
+ * selecting the correct flags to give lws_write() for each fragment.
+ *
+ * In the case of RFC8441 ws-over-h2, you cannot send ws fragments larger than
+ * the max h2 frame size, typically 16KB, but should further restrict it to
+ * the same ~2 x mtu limit mentioned above.
*/
LWS_VISIBLE LWS_EXTERN int
lws_write(struct lws *wsi, unsigned char *buf, size_t len,
* wsi.
*/
LWS_VISIBLE LWS_EXTERN int
-lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len)
+lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, size_t len)
LWS_WARN_DEPRECATED;
/**
* same tls backend, ie, OpenSSL or mbedTLS. The different backends
* produce different, incompatible representations for the same cert.
*/
+ LWS_TLS_CERT_INFO_DER_RAW,
+ /**< the certificate's raw DER representation. If it's too big,
+ * -1 is returned and the size will be returned in buf->ns.len.
+ * If the certificate cannot be found -1 is returned and 0 in
+ * buf->ns.len. */
};
union lws_tls_cert_info_results {
#endif
#define LWS_INSTALL_DATADIR "/usr/local/share"
+#define LWS_INSTALL_LIBDIR "/usr/local/lib"
#define LWS_LIBRARY_VERSION_MAJOR 4
-#define LWS_LIBRARY_VERSION_MINOR 0
-#define LWS_LIBRARY_VERSION_PATCH 22
+#define LWS_LIBRARY_VERSION_MINOR 2
+#define LWS_LIBRARY_VERSION_PATCH_ELABORATED 0-accepted/tizen/unified/20210602.122354-9-g8ca7310
+#define LWS_LIBRARY_VERSION_PATCH 0
+
/* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */
#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR * 1000000) + \
(LWS_LIBRARY_VERSION_MINOR * 1000) + \
LWS_LIBRARY_VERSION_PATCH
#define LWS_MAX_SMP 1
+/* #undef LWS_ESP_PLATFORM */
/* #undef LWS_LIBRARY_VERSION_NUMBER */
+/* #undef LWS_EXT_PTHREAD_LIBRARIES */
+
/* #undef LWS_AVOID_SIGPIPE_IGN */
-#define LWS_BUILD_HASH "d85b58c"
+#define LWS_BUILD_HASH "accepted/tizen/unified/20210602.122354-9-g8ca7310"
/* #undef LWS_BUILTIN_GETIFADDRS */
#define LWS_CLIENT_HTTP_PROXYING
/* #undef LWS_DETECTED_PLAT_IOS */
#define LWS_HAVE_BN_bn2binpad
#define LWS_HAVE_CLOCK_GETTIME
#define LWS_HAVE_EC_POINT_get_affine_coordinates
+#define LWS_HAVE_EC_KEY_new_by_curve_name
#define LWS_HAVE_ECDSA_SIG_set0
#define LWS_HAVE_EVP_MD_CTX_free
#define LWS_HAVE_EVP_aes_128_wrap
#define LWS_HAVE_EVP_aes_256_cfb8
#define LWS_HAVE_EVP_aes_256_cfb128
#define LWS_HAVE_EVP_aes_128_xts
+#define LWS_HAVE_EVP_PKEY_new_raw_private_key
#define LWS_HAVE_EXECVPE
+#define LWS_HAVE_LOCALTIME_R
+#define LWS_HAVE_GMTIME_R
+#define LWS_HAVE_CTIME_R
+#define LWS_HAVE_GETGRGID_R
+#define LWS_HAVE_GETGRNAM_R
+#define LWS_HAVE_GETPWUID_R
+#define LWS_HAVE_GETPWNAM_R
/* #undef LWS_HAVE_LIBCAP */
#define LWS_HAVE_HMAC_CTX_new
#define LWS_HAVE_MALLOC_H
#define LWS_HAVE_MALLOC_TRIM
#define LWS_HAVE_MALLOC_USABLE_SIZE
+/* #undef LWS_HAVE_mbedtls_md_setup */
/* #undef LWS_HAVE_mbedtls_net_init */
+/* #undef LWS_HAVE_mbedtls_rsa_complete */
+/* #undef LWS_HAVE_mbedtls_internal_aes_encrypt */
/* #undef LWS_HAVE_mbedtls_ssl_conf_alpn_protocols */
/* #undef LWS_HAVE_mbedtls_ssl_get_alpn_protocol */
/* #undef LWS_HAVE_mbedtls_ssl_conf_sni */
#define LWS_HAVE_RSA_SET0_KEY
/* #undef LWS_HAVE_RSA_verify_pss_mgf1 */
#define LWS_HAVE_SSL_CTX_get0_certificate
+/* #undef LWS_HAVE_SSL_CTX_load_verify_file */
+/* #undef LWS_HAVE_SSL_CTX_load_verify_dir */
#define LWS_HAVE_SSL_CTX_set1_param
-#define LWS_HAVE_SSL_CTX_set_ciphersuites
+/* #undef LWS_HAVE_SSL_CTX_set_ciphersuites */
#define LWS_HAVE_SSL_EXTRA_CHAIN_CERTS
#define LWS_HAVE_SSL_get0_alpn_selected
#define LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key
#define LWS_HAVE_SSL_set_alpn_protos
#define LWS_HAVE_SSL_SET_INFO_CALLBACK
+#define LWS_HAVE_SSL_SESSION_set_time
+/* #undef LWS_HAVE_SSL_SESSION_up_ref */
/* #undef LWS_HAVE__STAT32I64 */
#define LWS_HAVE_STDINT_H
/* #undef LWS_HAVE_SYS_CAPABILITY_H */
#define LWS_HAVE_TLS_CLIENT_METHOD
#define LWS_HAVE_TLSV1_2_CLIENT_METHOD
+#define LWS_HAVE_SUSECONDS_T
/* #undef LWS_HAVE_UV_VERSION_H */
#define LWS_HAVE_VFORK
#define LWS_HAVE_X509_get_key_usage
#define LWS_HAVE_X509_VERIFY_PARAM_set1_host
-#define LWS_LIBRARY_VERSION "4.0.22"
+#define LWS_LIBRARY_VERSION "4.2.0-accepted/tizen/unified/20210602.122354-9-g8ca7310"
#define LWS_LOGGING_BITFIELD_CLEAR 0
#define LWS_LOGGING_BITFIELD_SET 0
+#define LWS_LOG_TAG_LIFECYCLE
/* #undef LWS_MINGW_SUPPORT */
/* #undef LWS_NO_CLIENT */
#define LWS_NO_DAEMONIZE
/* #undef LWS_SHA1_USE_OPENSSL_NAME */
#define LWS_SSL_CLIENT_USE_OS_CA_CERTS
/* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */
+/* #undef LWS_SUPPRESS_DEPRECATED_API_WARNINGS */
+/* #undef LWS_TLS_LOG_PLAINTEXT_RX */
+/* #undef LWS_TLS_LOG_PLAINTEXT_TX */
/* #undef LWS_WITH_ABSTRACT */
/* #undef LWS_WITH_ACCESS_LOG */
/* #undef LWS_WITH_ACME */
/* #undef LWS_WITH_SYS_ASYNC_DNS */
/* #undef LWS_WITH_BORINGSSL */
/* #undef LWS_WITH_CGI */
+#define LWS_WITH_CONMON
#define LWS_WITH_CUSTOM_HEADERS
/* #undef LWS_WITH_DEPRECATED_LWS_DLL */
/* #undef LWS_WITH_DETAILED_LATENCY */
#define LWS_WITH_DIR
+/* #undef LWS_WITH_DRIVERS */
/* #undef LWS_WITH_ESP32 */
/* #undef LWS_HAVE_EVBACKEND_LINUXAIO */
/* #undef LWS_HAVE_EVBACKEND_IOURING */
#define LWS_WITH_EXTERNAL_POLL
-#define LWS_WITH_FILE_OPS
+/* #undef LWS_WITH_FILE_OPS */
/* #undef LWS_WITH_FSMOUNT */
/* #undef LWS_WITH_FTS */
/* #undef LWS_WITH_GENCRYPTO */
#define LWS_WITH_HTTP2
#define LWS_WITH_HTTP_BASIC_AUTH
/* #undef LWS_WITH_HTTP_BROTLI */
+/* #undef LWS_HTTP_HEADERS_ALL */
/* #undef LWS_WITH_HTTP_PROXY */
/* #undef LWS_WITH_HTTP_STREAM_COMPRESSION */
#define LWS_WITH_HTTP_UNCOMMON_HEADERS
/* #undef LWS_WITH_LIBEV */
/* #undef LWS_WITH_LIBEVENT */
/* #undef LWS_WITH_LIBUV */
+/* #undef LWS_WITH_SDEVENT */
#define LWS_WITH_LWSAC
#define LWS_LOGS_TIMESTAMP
/* #undef LWS_WITH_MBEDTLS */
/* #undef LWS_WITH_MINIZ */
+#define LWS_WITH_NETLINK
#define LWS_WITH_NETWORK
/* #undef LWS_WITH_NO_LOGS */
#define LWS_WITH_CLIENT
/* #undef LWS_WITH_SPAWN */
/* #undef LWS_WITH_PEER_LIMITS */
/* #undef LWS_WITH_PLUGINS */
+/* #undef LWS_WITH_PLUGINS_BUILTIN */
/* #undef LWS_WITH_POLARSSL */
#define LWS_WITH_POLL
/* #undef LWS_WITH_RANGES */
+/* #undef LWS_WITH_RFC6724 */
/* #undef LWS_WITH_SECURE_STREAMS */
+/* #undef LWS_WITH_SECURE_STREAMS_CPP */
/* #undef LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM */
/* #undef LWS_WITH_SECURE_STREAMS_PROXY_API */
+/* #undef LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY */
+/* #undef LWS_WITH_SECURE_STREAMS_AUTH_SIGV4 */
/* #undef LWS_WITH_SELFTESTS */
-#define LWS_WITH_SEQUENCER
+/* #undef LWS_WITH_SEQUENCER */
/* #undef LWS_WITH_SERVER_STATUS */
+#define LWS_WITH_SYS_SMD
/* #undef LWS_WITH_SMTP */
/* #undef LWS_WITH_SOCKS5 */
/* #undef LWS_WITH_STATEFUL_URLDECODE */
/* #undef LWS_WITH_STATS */
/* #undef LWS_WITH_STRUCT_SQLITE3 */
/* #undef LWS_WITH_STRUCT_JSON */
+/* #undef LWS_WITH_SUL_DEBUGGING */
/* #undef LWS_WITH_SQLITE3 */
-/* #undef LWS_WITH_SYS_NTPCLIENT */
/* #undef LWS_WITH_SYS_DHCP_CLIENT */
+/* #undef LWS_WITH_SYS_FAULT_INJECTION */
+/* #undef LWS_WITH_SYS_METRICS */
+/* #undef LWS_WITH_SYS_NTPCLIENT */
+#define LWS_WITH_SYS_STATE
/* #undef LWS_WITH_THREADPOOL */
#define LWS_WITH_TLS
+#define LWS_WITH_TLS_SESSIONS
#define LWS_WITH_UDP
-/* #undef LWS_WITH_UNIX_SOCK */
+/* #undef LWS_WITH_ULOOP */
+#define LWS_WITH_UNIX_SOCK
/* #undef LWS_WITH_ZIP_FOPS */
/* #undef USE_OLD_CYASSL */
/* #undef USE_WOLFSSL */
-
+/* #undef LWS_WITH_EVENT_LIBS */
+/* #undef LWS_WITH_EVLIB_PLUGINS */
+/* #undef LWS_WITH_LIBUV_INTERNAL */
+/* #undef LWS_WITH_PLUGINS_API */
+#define LWS_HAVE_RTA_PREF