1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

lws_netdev

This commit is contained in:
Andy Green 2020-06-22 20:05:06 +01:00
parent 65545d2d21
commit b72ab32c17
26 changed files with 1093 additions and 255 deletions

View file

@ -30,10 +30,11 @@ endif()
# Workaround for ESP-IDF
# Detect ESP_PLATFORM environment flag, if exist, set LWS_WITH_ESP32.
# Otherwise the user may not be able to run configuration ESP-IDF in the first time.
if(ESP_PLATFORM)
if (ESP_PLATFORM)
message(STATUS "ESP-IDF enabled")
set(LWS_WITH_ESP32 ON)
set(LWS_WITH_ZLIB OFF)
set(LWS_HAVE_mbedtls_ssl_get_alpn_protocol 1)
else()
set(LWS_WITH_ESP32_HELPER OFF)
endif()
@ -42,7 +43,7 @@ if (LWS_WITH_ESP32)
set(LWS_PLAT_FREERTOS 1)
endif()
if (LWS_PLAT_FREERTOS OR LWS_PLAT_OPTEE)
if (LWS_PLAT_OPTEE)
set(LWS_WITH_UDP 0)
endif()
@ -170,7 +171,6 @@ if (LWS_PLAT_FREERTOS)
endif()
if (LWS_PLAT_FREERTOS)
set(LWS_WITH_LWSAC 0)
set(LWS_WITH_FTS 0)
endif()

View file

@ -622,6 +622,7 @@ struct lws;
#include <libwebsockets/lws-ssd1306-i2c.h>
#include <libwebsockets/lws-ili9341-spi.h>
#include <libwebsockets/lws-settings.h>
#include <libwebsockets/lws-netdev.h>
#ifdef __cplusplus
}

View file

@ -70,6 +70,12 @@ struct pollfd {
#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"
#endif
#endif /* LWS_AMAZON_RTOS */
#if !defined(CONFIG_FREERTOS_HZ)

View file

@ -0,0 +1,158 @@
/*
* 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
typedef uint8_t lws_wifi_ch_t;
struct lws_netdev_instance;
/*
* 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);
void (*destroy)(struct lws_netdev_instance **pnd);
} lws_netdev_ops_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;
struct lws_context *ctx;
void *platinfo;
lws_dll2_t list;
} 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),
};
typedef struct lws_wifi_credentials {
uint8_t bssid[6];
char passphrase[64];
char ssid[33];
uint8_t alg;
} lws_wifi_credentials_t;
typedef struct lws_netdev_instance_wifi {
lws_netdev_instance_t inst;
lws_dll2_owner_t scan;
struct {
lws_wifi_credentials_t creds;
lws_sockaddr46 sa46[2];
uint8_t flags;
} ap;
struct {
lws_wifi_credentials_t creds;
lws_sockaddr46 sa46[2];
uint8_t flags;
} sta;
uint8_t flags;
} lws_netdev_instance_wifi_t;
/*
* Logical scan results sorted list item
*/
typedef struct lws_wifi_sta {
lws_dll2_t list;
uint8_t bssid[6];
uint8_t ssid_len;
lws_wifi_ch_t ch;
int8_t rssi[4];
uint8_t authmode;
uint8_t rssi_count;
uint8_t rssi_next;
/* ssid overallocated afterwards */
} lws_wifi_sta_t;
typedef struct lws_wifi_credentials_setting {
lws_dll2_t list;
lws_wifi_credentials_t creds;
} lws_wifi_credentials_setting_t;
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_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);
#define lws_netdev_wifi_plat_ops \
.create = lws_netdev_wifi_create_plat, \
.configure = lws_netdev_wifi_configure_plat, \
.up = lws_netdev_wifi_up_plat, \
.down = lws_netdev_wifi_down_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);

View file

@ -34,7 +34,7 @@
* Blobs have a further "filename" associated with them.
*/
#defined LSOOPEN_FLAG_WRITEABLE (1 << 0)
#define LSOOPEN_FLAG_WRITEABLE (1 << 0)
struct lws_settings_ops;

View file

@ -126,7 +126,9 @@ lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn)
if (!alpn)
return 0;
#if !defined(LWS_ESP_PLATFORM)
lwsl_info("%s: '%s'\n", __func__, alpn);
#endif
LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)
if (ar->alpn && !strcmp(ar->alpn, alpn) && ar->alpn_negotiated)

View file

@ -383,9 +383,9 @@ struct lws_context {
lws_async_dns_t async_dns;
#endif
struct lws_ss_handle *hss_fetch_policy;
#if defined(LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM)
struct lws_ss_handle *hss_auth;
struct lws_ss_handle *hss_fetch_policy;
lws_sorted_usec_list_t sul_api_amazon_com;
lws_sorted_usec_list_t sul_api_amazon_com_kick;
#endif

View file

@ -42,6 +42,7 @@ list(APPEND SOURCES
if (LWS_ESP_PLATFORM AND LWS_WITH_DRIVERS)
list(APPEND SOURCES plat/freertos/esp32/drivers/settings.c)
list(APPEND SOURCES plat/freertos/esp32/drivers/netdev/wifi.c)
endif()
if (LWS_WITH_ESP32_HELPER)
list(APPEND SOURCES plat/freertos/esp32/esp32-helpers.c)
@ -49,7 +50,7 @@ endif()
if (LWS_WITH_FILE_OPS)
list(APPEND SOURCES plat/freertos/freertos-file.c)
endif()
if (LWS_WITH_SYS_ASYNC_DNS)
if (LWS_WITH_SYS_ASYNC_DNS OR LWS_WITH_SYS_NTPCLIENT)
list(APPEND SOURCES plat/freertos/freertos-resolv.c)
endif()

View file

@ -0,0 +1,214 @@
/*
* 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.
*/
#include "private-lib-core.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_wifi.h"
#include <nvs_flash.h>
#include <esp_netif.h>
/*
static wifi_config_t config = {
.ap = {
.channel = 6,
.authmode = WIFI_AUTH_OPEN,
.max_connection = 1,
} };
*/
static wifi_config_t sta_config = {
.sta = {
.bssid_set = 0,
} };
static void
event_handler_wifi(void *arg, esp_event_base_t event_base, int32_t event_id,
void *event_data)
{
lws_netdev_instance_wifi_t *wnd = (lws_netdev_instance_wifi_t *)arg;
switch (event_id) {
case WIFI_EVENT_STA_START:
esp_wifi_connect();
break;
case WIFI_EVENT_STA_DISCONNECTED:
lwsl_err("%s: %s: disconnect -> wifi connect\n", __func__,
wnd->inst.name);
// !!! should only retry for a given amount of times
esp_wifi_connect();
break;
}
}
static void
event_handler_ip(void *arg, esp_event_base_t event_base, int32_t event_id,
void *event_data)
{
lws_netdev_instance_wifi_t *wnd = (lws_netdev_instance_wifi_t *)arg;
if (event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t *e = (ip_event_got_ip_t *)event_data;
char ip[16];
lws_write_numeric_address((void *)&e->ip_info.ip, 4, ip,
sizeof(ip));
lws_smd_msg_printf(wnd->inst.ctx, LWSSMDCL_NETWORK,
"{\"type\":\"ip\",\"if\":\"%s\","
"\"ipv4\":\"%s\"}", wnd->inst.name, ip);
}
}
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
/*
* This is the platform (esp-idf) init for any kind of networking to be
* available at all
*/
int
lws_netdev_plat_init(void)
{
nvs_flash_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
return 0;
}
/*
* This is the platform (esp-idf) init for any wifi to be available at all
*/
int
lws_netdev_plat_wifi_init(void)
{
wifi_init_config_t wic = WIFI_INIT_CONFIG_DEFAULT();
int n;
esp_netif_create_default_wifi_sta();
n = esp_wifi_init(&wic);
if (n) {
lwsl_err("%s: wifi init fail: %d\n", __func__, n);
return 1;
}
return 0;
}
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_netdev_instance_wifi_t *wnd = lws_zalloc(sizeof(*wnd), __func__);
if (!wnd)
return NULL;
wnd->inst.ops = ops;
wnd->inst.name = name;
wnd->inst.platinfo = platinfo;
wnd->inst.ctx = ctx;
return &wnd->inst;
}
int
lws_netdev_wifi_configure_plat(struct lws_netdev_instance *nd,
lws_netdev_config_t *config)
{
lws_netdev_instance_wifi_t *wnd = (lws_netdev_instance_wifi_t *)nd;
esp_wifi_set_mode(WIFI_MODE_STA);
lws_strncpy((char *)sta_config.sta.ssid, wnd->sta.creds.ssid,
sizeof(sta_config.sta.ssid));
lws_strncpy((char *)sta_config.sta.password, wnd->sta.creds.passphrase,
sizeof(sta_config.sta.password));
esp_wifi_set_config(WIFI_IF_STA, &sta_config);
return 0;
}
int
lws_netdev_wifi_up_plat(struct lws_netdev_instance *nd)
{
lws_netdev_instance_wifi_t *wnd = (lws_netdev_instance_wifi_t *)nd;
if (wnd->flags & LNDIW_UP)
return 0;
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler_ip,
nd,
&instance_got_ip));
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler_wifi,
nd,
&instance_any_id));
esp_wifi_start();
wnd->flags |= LNDIW_UP;
lws_smd_msg_printf(wnd->inst.ctx, LWSSMDCL_NETWORK,
"{\"type\":\"up\",\"if\":\"%s\"}", wnd->inst.name);
return 0;
}
int
lws_netdev_wifi_down_plat(struct lws_netdev_instance *nd)
{
lws_netdev_instance_wifi_t *wnd = (lws_netdev_instance_wifi_t *)nd;
if (!(wnd->flags & LNDIW_UP))
return 0;
lws_smd_msg_printf(wnd->inst.ctx, LWSSMDCL_NETWORK,
"{\"type\":\"down\",\"if\":\"%s\"}", wnd->inst.name);
esp_wifi_stop();
esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP,
&instance_got_ip);
esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID,
&instance_any_id);
wnd->flags &= ~LNDIW_UP;
return 0;
}
void
lws_netdev_wifi_destroy_plat(struct lws_netdev_instance **pnd)
{
lws_free(*pnd);
*pnd = NULL;
}

View file

@ -24,6 +24,7 @@
#include "private-lib-core.h"
#if defined(LWS_WITH_SYS_ASYNC_DNS)
lws_async_dns_server_check_t
lws_plat_asyncdns_init(struct lws_context *context, lws_sockaddr46 *sa46)
{
@ -40,20 +41,14 @@ lws_plat_asyncdns_init(struct lws_context *context, lws_sockaddr46 *sa46)
return s;
}
#endif
int
lws_plat_ntpclient_config(struct lws_context *context)
{
#if 0
char *ntpsrv = getenv("LWS_NTP_SERVER");
lws_system_blob_heap_append(lws_system_get_blob(context,
LWS_SYSBLOB_TYPE_NTP_SERVER, 0),
(const uint8_t *)"pool.ntp.org", 12);
if (ntpsrv && strlen(ntpsrv) < 64) {
lws_system_blob_heap_append(lws_system_get_blob(context,
LWS_SYSBLOB_TYPE_NTP_SERVER, 0),
(const uint8_t *)ntpsrv,
strlen(ntpsrv));
return 1;
}
#endif
return 0;
}

View file

@ -313,7 +313,7 @@ lws_plat_mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len)
if (errno == EPIPE || errno == ECONNRESET)
return MBEDTLS_ERR_NET_CONN_RESET;
if (errno == EINTR)
if (errno == EINTR || !errno)
return MBEDTLS_ERR_SSL_WANT_READ;
return MBEDTLS_ERR_NET_RECV_FAILED;

View file

@ -705,13 +705,16 @@ ads_known:
wsi->detlat.earliest_write_req_pre_write = lws_now_usecs();
#endif
#if defined(LWS_ESP_PLATFORM)
errno = 0;
#endif
m = connect(wsi->desc.sockfd, (const struct sockaddr *)psa, n);
if (m == -1) {
int errno_copy = LWS_ERRNO;
lwsl_debug("%s: connect says errno: %d\n", __func__, errno_copy);
if (errno_copy != LWS_EALREADY &&
if (errno_copy && errno_copy != LWS_EALREADY &&
errno_copy != LWS_EINPROGRESS &&
errno_copy != LWS_EWOULDBLOCK
#ifdef _WIN32

View file

@ -146,8 +146,10 @@ callback_ntpc(struct lws *wsi, enum lws_callback_reasons reason, void *user,
if (!lws_system_get_ops(wsi->context) ||
!lws_system_get_ops(wsi->context)->set_clock) {
#if !defined(LWS_ESP_PLATFORM)
lwsl_err("%s: set up system ops for set_clock\n",
__func__);
#endif
// return -1;
}
@ -163,8 +165,11 @@ callback_ntpc(struct lws *wsi, enum lws_callback_reasons reason, void *user,
lws_system_blob_get_single_ptr(lws_system_get_blob(
v->context, LWS_SYSBLOB_TYPE_NTP_SERVER, 0),
(const uint8_t **)&v->ntp_server_ads);
if (!v->ntp_server_ads || v->ntp_server_ads[0] == '\0')
v->ntp_server_ads = "pool.ntp.org";
lwsl_info("%s: using ntp server %s\n", __func__, v->ntp_server_ads);
lwsl_info("%s: using ntp server %s\n", __func__,
v->ntp_server_ads);
lws_ntpc_retry_conn(&v->sul_conn);
break;
@ -222,7 +227,19 @@ do_close:
lwsl_notice("%s: Unix time: %llu\n", __func__,
(unsigned long long)ns / 1000000000);
// lws_system_get_ops(wsi->context)->set_clock(ns / 1000);
#if defined(LWS_ESP_PLATFORM)
{
struct timeval t;
t.tv_sec = (unsigned long long)ns / 1000000000;
t.tv_usec = (ns % 1000000000) / 1000;
settimeofday(&t, NULL);
}
#endif
if (lws_system_get_ops(wsi->context) &&
lws_system_get_ops(wsi->context)->set_clock)
lws_system_get_ops(wsi->context)->set_clock(ns / 1000);
v->set_time = 1;
lws_state_transition_steps(&wsi->context->mgr_system,

View file

@ -9,6 +9,10 @@ if (ESP_PLATFORM)
option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" ON)
set(LWS_WITH_DRIVERS ON)
option(LWS_WITH_SECURE_STREAMS "With secure streams" ON)
set(LWS_WITH_SECURE_STREAMS ON)
option(LWS_WITH_LWSAC "With lwsac" ON)
set(LWS_WITH_LWSAC ON)
add_subdirectory(libwebsockets)

View file

@ -1,5 +1,5 @@
idf_component_register(SRCS
"lws-minimal-esp32.c"
lws-minimal-esp32.c devices.c
INCLUDE_DIRS "../libwebsockets/include;${IDF_PATH}/components/spi_flash/include;${IDF_PATH}/components/nvs_flash/include;${IDF_PATH}/components/mdns/include")
target_link_libraries(${COMPONENT_LIB} websockets)

View file

@ -16,11 +16,7 @@
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_wifi.h"
#include <nvs_flash.h>
#include <esp_netif.h>
#include <driver/gpio.h>
#include <libwebsockets.h>
@ -29,6 +25,7 @@ struct lws_context *context;
lws_sorted_usec_list_t sul;
struct lws_led_state *lls;
lws_display_state_t lds;
lws_netdev_instance_wifi_t *wnd;
int interrupted;
/*
@ -114,6 +111,10 @@ static const lws_led_gpio_controller_t lgc = {
.count_leds = LWS_ARRAY_SIZE(lgm)
};
static const lws_netdev_ops_t wifi_ops = {
lws_netdev_wifi_plat_ops
};
static const uint8_t img[] = {
#include "../banded-img.h"
};
@ -161,20 +162,14 @@ sul_cb(lws_sorted_usec_list_t *sul)
void
app_main(void)
{
wifi_init_config_t wic = WIFI_INIT_CONFIG_DEFAULT();
struct lws_context_creation_info info;
struct lws_button_state *bcs;
int n = 0;
lws_set_log_level(15, NULL);
nvs_flash_init();
esp_netif_init();
n = esp_wifi_init(&wic);
if (n) {
lwsl_err("%s: wifi init fail: %d\n", __func__, n);
goto spin;
}
lws_netdev_plat_init();
lws_netdev_plat_wifi_init();
memset(&info, 0, sizeof(info));
@ -191,6 +186,25 @@ app_main(void)
return;
}
/* create the wifi network device and configure it */
wnd = (lws_netdev_instance_wifi_t *)
wifi_ops.create(context, &wifi_ops, "wl0", NULL);
if (!wnd) {
lwsl_err("%s: failed to create wifi object\n", __func__);
goto spin;
}
strcpy(wnd->sta.creds.ssid, "xxx");
strcpy(wnd->sta.creds.passphrase, "yyy");
wnd->flags |= LNDIW_MODE_STA;
if (wifi_ops.configure(&wnd->inst, NULL)) {
lwsl_err("%s: failed to configure wifi object\n", __func__);
goto spin;
}
wifi_ops.up(&wnd->inst);
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);

View file

@ -0,0 +1,134 @@
static const char * const ss_policy =
"{"
"\"release\":" "\"01234567\","
"\"product\":" "\"myproduct\","
"\"schema-version\":" "1,"
"\"retry\": [" /* named backoff / retry strategies */
"{\"default\": {"
"\"backoff\": [" "1000,"
"2000,"
"3000,"
"5000,"
"10000"
"],"
"\"conceal\":" "25,"
"\"jitterpc\":" "20,"
"\"svalidping\":" "30,"
"\"svalidhup\":" "35"
"}}"
"],"
"\"certs\": [" /* named individual certificates in BASE64 DER */
/*
* Let's Encrypt certs for warmcat.com / libwebsockets.org
*
* We fetch the real policy from there using SS and switch to
* using that.
*/
"{\"isrg_root_x1\": \"" /* ISRG ROOT X1 */
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw"
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh"
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4"
"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu"
"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY"
"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc"
"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+"
"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U"
"A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW"
"T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH"
"B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC"
"B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv"
"KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn"
"OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn"
"jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw"
"qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI"
"rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV"
"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq"
"hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL"
"ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ"
"3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK"
"NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5"
"ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur"
"TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC"
"jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc"
"oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq"
"4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA"
"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d"
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc="
"\"},"
"{\"LEX3_isrg_root_x1\": \"" /* LE X3 signed by ISRG X1 root */
"MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw"
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh"
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0MzU1"
"WhcNMjExMDA2MTU0MzU1WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg"
"RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwggEi"
"MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc0wzwWuUuR7dyXTeDs2hjMOrX"
"NSYZJeG9vjXxcJIvt7hLQQWrqZ41CFjssSrEaIcLo+N15Obzp2JxunmBYB/XkZqf"
"89B4Z3HIaQ6Vkc/+5pnpYDxIzH7KTXcSJJ1HG1rrueweNwAcnKx7pwXqzkrrvUHl"
"Npi5y/1tPJZo3yMqQpAMhnRnyH+lmrhSYRQTP2XpgofL2/oOVvaGifOFP5eGr7Dc"
"Gu9rDZUWfcQroGWymQQ2dYBrrErzG5BJeC+ilk8qICUpBMZ0wNAxzY8xOJUWuqgz"
"uEPxsR/DMH+ieTETPS02+OP88jNquTkxxa/EjQ0dZBYzqvqEKbbUC8DYfcOTAgMB"
"AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU"
"BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB"
"FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBSo"
"SmpjBH3duubRObemRWXv86jsoTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js"
"LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF"
"BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG"
"AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD"
"VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB"
"ABnPdSA0LTqmRf/Q1eaM2jLonG4bQdEnqOJQ8nCqxOeTRrToEKtwT++36gTSlBGx"
"A/5dut82jJQ2jxN8RI8L9QFXrWi4xXnA2EqA10yjHiR6H9cj6MFiOnb5In1eWsRM"
"UM2v3e9tNsCAgBukPHAg1lQh07rvFKm/Bz9BCjaxorALINUfZ9DD64j2igLIxle2"
"DPxW8dI/F2loHMjXZjqG8RkqZUdoxtID5+90FgsGIfkMpqgRS05f4zPbCEHqCXl1"
"eO5HyELTgcVlLXXQDgAWnRzut1hFJeczY1tjQQno6f6s+nMydLN26WuU4s3UYvOu"
"OsUxRlJu7TSRHqDC3lSE5XggVkzdaPkuKGQbGpny+01/47hfXXNB7HntWNZ6N2Vw"
"p7G6OfY+YQrZwIaQmhrIqJZuigsrbe3W+gdn5ykE9+Ky0VgVUsfxo52mwFYs1JKY"
"2PGDuWx8M6DlS6qQkvHaRUo0FMd8TsSlbF0/v965qGFKhSDeQoMpYnwcmQilRh/0"
"ayLThlHLN81gSkJjVrPI0Y8xCVPB4twb1PFUd2fPM3sA1tJ83sZ5v8vgFv2yofKR"
"PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b"
"rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt"
"\"}"
"],"
"\"trust_stores\": [" /* named cert chains */
"{"
"\"name\": \"le_via_isrg\","
"\"stack\": ["
"\"isrg_root_x1\","
"\"LEX3_isrg_root_x1\""
"]"
"}"
"],"
"\"s\": ["
"{\"test_stream\": {"
"\"endpoint\":" "\"warmcat.com\","
"\"port\":" "443,"
"\"protocol\":" "\"h2\","
"\"http_method\":" "\"GET\","
"\"http_url\":" "\"index.html\","
"\"tls\":" "true,"
"\"opportunistic\":" "true,"
"\"retry\":" "\"default\","
"\"tls_trust_store\":" "\"le_via_isrg\""
"}},{"
/*
* "captive_portal_detect" describes
* what to do in order to check if the path to
* the Internet is being interrupted by a
* captive portal.
*/
"\"captive_portal_detect\": {"
"\"endpoint\":" "\"connectivitycheck.android.com\","
"\"http_url\":" "\"generate_204\","
"\"port\":" "80,"
"\"protocol\":" "\"h1\","
"\"http_method\":" "\"GET\","
"\"opportunistic\":" "true,"
"\"http_expect\":" "204,"
"\"http_fail_redirect\": true"
"}}"
"]}"
;

View file

@ -88,7 +88,7 @@
#define CONFIG_ESP_ERR_TO_NAME_LOOKUP 1
#define CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE 32
#define CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE 2304
#define CONFIG_ESP_MAIN_TASK_STACK_SIZE 3584
#define CONFIG_ESP_MAIN_TASK_STACK_SIZE 6584
#define CONFIG_ESP_IPC_TASK_STACK_SIZE 1024
#define CONFIG_ESP_IPC_USES_CALLERS_PRIORITY 1
#define CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE 2048

View file

@ -9,6 +9,12 @@ if (ESP_PLATFORM)
option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" ON)
set(LWS_WITH_DRIVERS ON)
option(LWS_WITH_SECURE_STREAMS "With secure streams" ON)
set(LWS_WITH_SECURE_STREAMS ON)
option(LWS_WITH_LWSAC "With lwsac" ON)
set(LWS_WITH_LWSAC ON)
option(LWS_WITH_SYS_NTPCLIENT "With ntpclient" ON)
set(LWS_WITH_SYS_NTPCLIENT ON)
add_subdirectory(libwebsockets)

View file

@ -1,5 +1,6 @@
idf_component_register(SRCS
"lws-minimal-esp32.c"
lws-minimal-esp32.c
devices.c
INCLUDE_DIRS "../libwebsockets/include;${IDF_PATH}/components/spi_flash/include;${IDF_PATH}/components/nvs_flash/include;${IDF_PATH}/components/mdns/include")
target_link_libraries(${COMPONENT_LIB} websockets)

View file

@ -0,0 +1,231 @@
/*
* devices for ESP WROVER KIT
*
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#define LWIP_PROVIDE_ERRNO 1
#define _ESP_PLATFORM_ERRNO_H_
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <driver/gpio.h>
#include <libwebsockets.h>
struct lws_led_state *lls;
lws_display_state_t lds;
struct lws_button_state *bcs;
lws_netdev_instance_wifi_t *wnd;
/*
* Button controller
*
* On the WROVER KIT, it's a bit overloaded... the two buttons are reset and
* gpio0, gpio is also used for one of the RGB LEDs channels control so it's not
* really usable as a general user button.
*
* Instead we use GPIO 14 (available on J1) for a button with the other side
* of the switch connected to 0V.
*/
static const lws_button_map_t bcm[] = {
{
.gpio = GPIO_NUM_14,
.smd_interaction_name = "user"
},
};
static const lws_button_controller_t bc = {
.smd_bc_name = "bc",
.gpio_ops = &lws_gpio_plat,
.button_map = &bcm[0],
.active_state_bitmap = 0,
.count_buttons = LWS_ARRAY_SIZE(bcm),
};
/*
* pwm controller
*/
static const lws_pwm_map_t pwm_map[] = {
{ .gpio = GPIO_NUM_2, .index = 0, .active_level = 1 },
{ .gpio = GPIO_NUM_0, .index = 1, .active_level = 1 },
{ .gpio = GPIO_NUM_4, .index = 2, .active_level = 1 },
{ .gpio = GPIO_NUM_5, .index = 3, .active_level = 0 }
};
static const lws_pwm_ops_t pwm_ops = {
lws_pwm_plat_ops,
.pwm_map = &pwm_map[0],
.count_pwm_map = LWS_ARRAY_SIZE(pwm_map)
};
/*
* led controller
*/
static const lws_led_gpio_map_t lgm[] = {
{
.name = "red",
.gpio = GPIO_NUM_2,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
{
.name = "green",
.gpio = GPIO_NUM_0,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
{
.name = "blue",
.gpio = GPIO_NUM_4,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
{
.name = "backlight",
.gpio = GPIO_NUM_5,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 0,
/*
* The wrover kit uses a 2 NPN in series to drive the backlight
* which means if the GPIO provides no current, the backlight is
* full-on. This causes a white flash during boot... they mark
* the first stage with "Modify In ESP-WROVER-KIT!" on the
* schematics but on Kit v4.1, it's still like that.
*/
},
};
static const lws_led_gpio_controller_t lgc = {
.led_ops = lws_led_gpio_ops,
.gpio_ops = &lws_gpio_plat,
.led_map = &lgm[0],
.count_leds = LWS_ARRAY_SIZE(lgm)
};
/*
* Bitbang SPI configuration for display
*/
static const lws_bb_spi_t lbspi = {
.bb_ops = {
lws_bb_spi_ops,
.bus_mode = LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_RISING
},
.gpio = &lws_gpio_plat,
.clk = GPIO_NUM_19,
.ncs = { GPIO_NUM_22 },
.ncmd = { GPIO_NUM_21 },
.mosi = GPIO_NUM_23,
.miso = GPIO_NUM_25,
.flags = LWSBBSPI_FLAG_USE_NCS0 |
LWSBBSPI_FLAG_USE_NCMD0
};
/*
* SPI display
*/
static const lws_display_ili9341_t disp = {
.disp = {
lws_display_ili9341_ops,
.bl_pwm_ops = &pwm_ops,
.bl_active = &lws_pwmseq_static_on,
.bl_dim = &lws_pwmseq_static_half,
.bl_transition = &lws_pwmseq_linear_wipe,
.bl_index = 3,
.w = 320,
.h = 240,
.latency_wake_ms = 150,
},
.spi = (lws_spi_ops_t *)&lbspi,
.gpio = &lws_gpio_plat,
.reset_gpio = GPIO_NUM_18,
.spi_index = 0
};
/*
*
*/
/*
* Wifi
*/
static const lws_netdev_ops_t wifi_ops = {
lws_netdev_wifi_plat_ops
};
int
init_plat_devices(struct lws_context *context)
{
/* create the wifi network device and configure it */
wnd = (lws_netdev_instance_wifi_t *)
wifi_ops.create(context, &wifi_ops, "wl0", NULL);
if (!wnd) {
lwsl_err("%s: failed to create wifi object\n", __func__);
return 1;
}
strcpy(wnd->sta.creds.ssid, "xxx");
strcpy(wnd->sta.creds.passphrase, "yyy");
wnd->flags |= LNDIW_MODE_STA;
if (wifi_ops.configure(&wnd->inst, NULL)) {
lwsl_err("%s: failed to configure wifi object\n", __func__);
return 1;
}
wifi_ops.up(&wnd->inst);
/* bring up the led controller */
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);
return 1;
}
/* pwm init must go after the led controller init */
pwm_ops.init(&pwm_ops);
/* ... and the button controller */
bcs = lws_button_controller_create(context, &bc);
if (!bcs) {
lwsl_err("%s: could not create buttons\n", __func__);
return 1;
}
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
/* ... bring up spi bb and the display */
lbspi.bb_ops.init(&lbspi.bb_ops);
lws_display_state_init(&lds, context, 30000, 10000, lls, &disp.disp);
/*
* Make the RGB LED do something using sequenced PWM... pressing the
* GPIO14 button with single-presses advances the blue channel between
* different sequences
*/
lws_led_transition(lls, "blue", &lws_pwmseq_sine_endless_fast,
&lws_pwmseq_linear_wipe);
lws_led_transition(lls, "green", &lws_pwmseq_sine_endless_slow,
&lws_pwmseq_linear_wipe);
lws_led_transition(lls, "red", &lws_pwmseq_sine_endless_slow,
&lws_pwmseq_linear_wipe);
return 0;
}

View file

@ -7,6 +7,9 @@
* Universal Public Domain Dedication.
*
* Configured for ESP32 WROVER KIT
*
* What should be notable about this is there are no esp-idf apis used here or
* any related files, despite we are running on top of stock esp-idf.
*/
#define LWIP_PROVIDE_ERRNO 1
@ -16,158 +19,97 @@
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_wifi.h"
#include <nvs_flash.h>
#include <esp_netif.h>
#include <driver/gpio.h>
#include <libwebsockets.h>
struct lws_context *context;
lws_sorted_usec_list_t sul;
struct lws_led_state *lls;
lws_display_state_t lds;
extern struct lws_led_state *lls;
extern lws_display_state_t lds;
extern struct lws_button_state *bcs;
extern lws_netdev_instance_wifi_t *wnd;
int interrupted;
extern int init_plat_devices(struct lws_context *);
static const uint8_t logo[] = {
#include "cat-565.h"
};
/*
* Button controller
*
* On the WROVER KIT, it's a bit overloaded... the two buttons are reset and
* gpio0, gpio is also used for one of the RGB LEDs channels control so it's not
* really usable as a general user button.
*
* Instead we use GPIO 14 (available on J1) for a button with the other side
* of the switch connected to 0V.
*/
static const lws_button_map_t bcm[] = {
{
.gpio = GPIO_NUM_14,
.smd_interaction_name = "user"
},
};
static const lws_button_controller_t bc = {
.smd_bc_name = "bc",
.gpio_ops = &lws_gpio_plat,
.button_map = &bcm[0],
.active_state_bitmap = 0,
.count_buttons = LWS_ARRAY_SIZE(bcm),
};
/*
* pwm controller
*/
static const lws_pwm_map_t pwm_map[] = {
{ .gpio = GPIO_NUM_2, .index = 0, .active_level = 1 },
{ .gpio = GPIO_NUM_0, .index = 1, .active_level = 1 },
{ .gpio = GPIO_NUM_4, .index = 2, .active_level = 1 },
{ .gpio = GPIO_NUM_5, .index = 3, .active_level = 0 }
};
static const lws_pwm_ops_t pwm_ops = {
lws_pwm_plat_ops,
.pwm_map = &pwm_map[0],
.count_pwm_map = LWS_ARRAY_SIZE(pwm_map)
};
/*
* led controller
*/
static const lws_led_gpio_map_t lgm[] = {
{
.name = "red",
.gpio = GPIO_NUM_2,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
{
.name = "green",
.gpio = GPIO_NUM_0,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
{
.name = "blue",
.gpio = GPIO_NUM_4,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
{
.name = "backlight",
.gpio = GPIO_NUM_5,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 0,
/*
* The wrover kit uses a 2 NPN in series to drive the backlight
* which means if the GPIO provides no current, the backlight is
* full-on. This causes a white flash during boot... they mark
* the first stage with "Modify In ESP-WROVER-KIT!" on the
* schematics but on Kit v4.1, it's still like that.
*/
},
};
static const lws_led_gpio_controller_t lgc = {
.led_ops = lws_led_gpio_ops,
.gpio_ops = &lws_gpio_plat,
.led_map = &lgm[0],
.count_leds = LWS_ARRAY_SIZE(lgm)
};
/*
* Bitbang SPI configuration for display
*/
static const lws_bb_spi_t lbspi = {
.bb_ops = {
lws_bb_spi_ops,
.bus_mode = LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_RISING
},
.gpio = &lws_gpio_plat,
.clk = GPIO_NUM_19,
.ncs = { GPIO_NUM_22 },
.ncmd = { GPIO_NUM_21 },
.mosi = GPIO_NUM_23,
.miso = GPIO_NUM_25,
.flags = LWSBBSPI_FLAG_USE_NCS0 |
LWSBBSPI_FLAG_USE_NCMD0
};
/*
* SPI display
*/
static const lws_display_ili9341_t disp = {
.disp = {
lws_display_ili9341_ops,
.bl_pwm_ops = &pwm_ops,
.bl_active = &lws_pwmseq_static_on,
.bl_dim = &lws_pwmseq_static_half,
.bl_transition = &lws_pwmseq_linear_wipe,
.bl_index = 3,
.w = 320,
.h = 240,
.latency_wake_ms = 150,
},
.spi = (lws_spi_ops_t *)&lbspi,
.gpio = &lws_gpio_plat,
.reset_gpio = GPIO_NUM_18,
.spi_index = 0
};
#include "policy.h"
static uint8_t flip;
typedef struct myss {
struct lws_ss_handle *ss;
void *opaque_data;
/* ... application specific state ... */
size_t amount;
} myss_t;
static int
myss_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
{
myss_t *m = (myss_t *)userobj;
lwsl_user("%s: len %d, flags: %d\n", __func__, (int)len, flags);
// lwsl_hexdump_info(buf, len);
m->amount += len;
if (flags & LWSSS_FLAG_EOM) {
/*
* If we received the whole message, for our example it means
* we are done.
*/
lwsl_notice("%s: received %u bytes\n", __func__,
(unsigned int)m->amount);
/*
* In CI, we use sai-expect to look for this
* string for success
*/
lwsl_notice("Completed: PASS\n");
}
return 0;
}
static int
myss_state(void *userobj, void *sh, lws_ss_constate_t state,
lws_ss_tx_ordinal_t ack)
{
myss_t *m = (myss_t *)userobj;
lwsl_user("%s: %s, ord 0x%x\n", __func__, lws_ss_state_name(state),
(unsigned int)ack);
switch (state) {
case LWSSSCS_CREATING:
lws_ss_client_connect(m->ss);
break;
default:
break;
}
return 0;
}
static const lws_ss_info_t ssi = {
.handle_offset = offsetof(myss_t, ss),
.opaque_user_data_offset = offsetof(myss_t, opaque_data),
.rx = myss_rx,
.state = myss_state,
.user_alloc = sizeof(myss_t),
.streamtype = "test_stream",
};
static const lws_led_sequence_def_t *seqs[] = {
&lws_pwmseq_static_on,
&lws_pwmseq_static_off,
@ -180,119 +122,94 @@ smd_cb(void *opaque, lws_smd_class_t _class, lws_usec_t timestamp, void *buf,
size_t len)
{
if (!lws_json_simple_strcmp(buf, len, "\"src\":", "bc/user")) {
if (!lws_json_simple_strcmp(buf, len, "\"event\":", "click")) {
lws_led_transition(lls, "blue", seqs[flip & 3],
&lws_pwmseq_linear_wipe);
flip++;
}
if (!lws_json_simple_strcmp(buf, len, "\"src\":", "bc/user") &&
!lws_json_simple_strcmp(buf, len, "\"event\":", "click")) {
lws_led_transition(lls, "blue", seqs[flip & 3],
&lws_pwmseq_linear_wipe);
flip++;
}
lwsl_hexdump_notice(buf, len);
/*
* Any kind of user interaction brings the display back up and resets
* the dimming and blanking timers
*/
lws_display_state_active(&lds);
if ((_class & LWSSMDCL_SYSTEM_STATE) &&
!lws_json_simple_strcmp(buf, len, "\"state\":", "OPERATIONAL")) {
/* create the secure stream */
lwsl_notice("%s: creating test secure stream\n", __func__);
if (lws_ss_create(context, 0, &ssi, NULL, NULL, NULL, NULL)) {
lwsl_err("%s: failed to create secure stream\n",
__func__);
return -1;
}
}
if (_class & LWSSMDCL_INTERACTION)
/*
* Any kind of user interaction brings the display back up and
* resets the dimming / blanking timers
*/
lws_display_state_active(&lds);
return 0;
}
static void
sul_cb(lws_sorted_usec_list_t *sul)
{
/* In CI, we use sai-expect to look for this string for success */
lwsl_notice("Completed: PASS\n");
}
void
app_main(void)
{
wifi_init_config_t wic = WIFI_INIT_CONFIG_DEFAULT();
struct lws_context_creation_info info;
struct lws_button_state *bcs;
int n = 0;
struct lws_context_creation_info *info;
lws_set_log_level(1024 | 15, NULL);
nvs_flash_init();
esp_netif_init();
n = esp_wifi_init(&wic);
if (n) {
lwsl_err("%s: wifi init fail: %d\n", __func__, n);
goto spin;
}
lws_netdev_plat_init();
lws_netdev_plat_wifi_init();
memset(&info, 0, sizeof(info));
info = malloc(sizeof(*info));
if (!info)
goto spin;
memset(info, 0, sizeof(*info));
lwsl_notice("LWS test for Espressif ESP32 WROVER KIT\n");
info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
info.port = CONTEXT_PORT_NO_LISTEN;
info.early_smd_cb = smd_cb;
info.early_smd_class_filter = LWSSMDCL_INTERACTION;
info->pss_policies_json = ss_policy;
info->options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
info->port = CONTEXT_PORT_NO_LISTEN;
info->early_smd_cb = smd_cb;
info->early_smd_class_filter = LWSSMDCL_INTERACTION |
LWSSMDCL_SYSTEM_STATE |
LWSSMDCL_NETWORK;
context = lws_create_context(&info);
context = lws_create_context(info);
if (!context) {
lwsl_err("lws init failed\n");
return;
}
/* bring up the led controller */
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);
goto spin;
}
/* pwm init must go after the led controller init */
/*
* We don't need this after context creation... things it pointed to
* still need to exist though since the context copied the pointers.
*/
pwm_ops.init(&pwm_ops);
free(info);
/* ... and the button controller */
/* devices and init are in devices.c */
bcs = lws_button_controller_create(context, &bc);
if (!bcs) {
lwsl_err("%s: could not create buttons\n", __func__);
if (init_plat_devices(context))
goto spin;
}
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
/* ... bring up spi bb and the display */
lbspi.bb_ops.init(&lbspi.bb_ops);
lws_display_state_init(&lds, context, 30000, 10000, lls, &disp.disp);
/* put the cat picture up there and enable the backlight */
disp.disp.blit(lds.disp, logo, 0, 0, 320, 240);
lds.disp->blit(lds.disp, logo, 0, 0, 320, 240);
lws_display_state_active(&lds);
/*
* Make the RGB LED do something using sequenced PWM... pressing the
* GPIO14 button with single-presses advances the blue channel between
* different sequences
*/
lws_sul_schedule(context, 0, &sul, sul_cb, 3 * LWS_USEC_PER_SEC);
lws_led_transition(lls, "blue", &lws_pwmseq_sine_endless_fast,
&lws_pwmseq_linear_wipe);
lws_led_transition(lls, "green", &lws_pwmseq_sine_endless_slow,
&lws_pwmseq_linear_wipe);
lws_led_transition(lls, "red", &lws_pwmseq_sine_endless_slow,
&lws_pwmseq_linear_wipe);
/*
* We say the test succeeded if we survive 3s around the event loop
*/
while (n >= 0 && !interrupted) {
n = lws_service(context, 0);
do {
taskYIELD();
}
} while (lws_service(context, 0) >= 0 && !interrupted);
lwsl_notice("%s: exited event loop\n", __func__);
lws_context_destroy(context);

View file

@ -0,0 +1,134 @@
static const char * const ss_policy =
"{"
"\"release\":" "\"01234567\","
"\"product\":" "\"myproduct\","
"\"schema-version\":" "1,"
"\"retry\": [" /* named backoff / retry strategies */
"{\"default\": {"
"\"backoff\": [" "1000,"
"2000,"
"3000,"
"5000,"
"10000"
"],"
"\"conceal\":" "25,"
"\"jitterpc\":" "20,"
"\"svalidping\":" "30,"
"\"svalidhup\":" "35"
"}}"
"],"
"\"certs\": [" /* named individual certificates in BASE64 DER */
/*
* Let's Encrypt certs for warmcat.com / libwebsockets.org
*
* We fetch the real policy from there using SS and switch to
* using that.
*/
"{\"isrg_root_x1\": \"" /* ISRG ROOT X1 */
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw"
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh"
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4"
"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu"
"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY"
"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc"
"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+"
"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U"
"A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW"
"T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH"
"B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC"
"B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv"
"KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn"
"OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn"
"jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw"
"qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI"
"rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV"
"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq"
"hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL"
"ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ"
"3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK"
"NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5"
"ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur"
"TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC"
"jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc"
"oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq"
"4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA"
"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d"
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc="
"\"},"
"{\"LEX3_isrg_root_x1\": \"" /* LE X3 signed by ISRG X1 root */
"MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw"
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh"
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0MzU1"
"WhcNMjExMDA2MTU0MzU1WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg"
"RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwggEi"
"MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc0wzwWuUuR7dyXTeDs2hjMOrX"
"NSYZJeG9vjXxcJIvt7hLQQWrqZ41CFjssSrEaIcLo+N15Obzp2JxunmBYB/XkZqf"
"89B4Z3HIaQ6Vkc/+5pnpYDxIzH7KTXcSJJ1HG1rrueweNwAcnKx7pwXqzkrrvUHl"
"Npi5y/1tPJZo3yMqQpAMhnRnyH+lmrhSYRQTP2XpgofL2/oOVvaGifOFP5eGr7Dc"
"Gu9rDZUWfcQroGWymQQ2dYBrrErzG5BJeC+ilk8qICUpBMZ0wNAxzY8xOJUWuqgz"
"uEPxsR/DMH+ieTETPS02+OP88jNquTkxxa/EjQ0dZBYzqvqEKbbUC8DYfcOTAgMB"
"AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU"
"BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB"
"FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBSo"
"SmpjBH3duubRObemRWXv86jsoTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js"
"LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF"
"BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG"
"AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD"
"VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB"
"ABnPdSA0LTqmRf/Q1eaM2jLonG4bQdEnqOJQ8nCqxOeTRrToEKtwT++36gTSlBGx"
"A/5dut82jJQ2jxN8RI8L9QFXrWi4xXnA2EqA10yjHiR6H9cj6MFiOnb5In1eWsRM"
"UM2v3e9tNsCAgBukPHAg1lQh07rvFKm/Bz9BCjaxorALINUfZ9DD64j2igLIxle2"
"DPxW8dI/F2loHMjXZjqG8RkqZUdoxtID5+90FgsGIfkMpqgRS05f4zPbCEHqCXl1"
"eO5HyELTgcVlLXXQDgAWnRzut1hFJeczY1tjQQno6f6s+nMydLN26WuU4s3UYvOu"
"OsUxRlJu7TSRHqDC3lSE5XggVkzdaPkuKGQbGpny+01/47hfXXNB7HntWNZ6N2Vw"
"p7G6OfY+YQrZwIaQmhrIqJZuigsrbe3W+gdn5ykE9+Ky0VgVUsfxo52mwFYs1JKY"
"2PGDuWx8M6DlS6qQkvHaRUo0FMd8TsSlbF0/v965qGFKhSDeQoMpYnwcmQilRh/0"
"ayLThlHLN81gSkJjVrPI0Y8xCVPB4twb1PFUd2fPM3sA1tJ83sZ5v8vgFv2yofKR"
"PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b"
"rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt"
"\"}"
"],"
"\"trust_stores\": [" /* named cert chains */
"{"
"\"name\": \"le_via_isrg\","
"\"stack\": ["
"\"isrg_root_x1\","
"\"LEX3_isrg_root_x1\""
"]"
"}"
"],"
"\"s\": ["
"{\"test_stream\": {"
"\"endpoint\":" "\"warmcat.com\","
"\"port\":" "443,"
"\"protocol\":" "\"h2\","
"\"http_method\":" "\"GET\","
"\"http_url\":" "\"index.html\","
"\"tls\":" "true,"
"\"opportunistic\":" "true,"
"\"retry\":" "\"default\","
"\"tls_trust_store\":" "\"le_via_isrg\""
"}},{"
/*
* "captive_portal_detect" describes
* what to do in order to check if the path to
* the Internet is being interrupted by a
* captive portal.
*/
"\"captive_portal_detect\": {"
"\"endpoint\":" "\"connectivitycheck.android.com\","
"\"http_url\":" "\"generate_204\","
"\"port\":" "80,"
"\"protocol\":" "\"h1\","
"\"http_method\":" "\"GET\","
"\"opportunistic\":" "true,"
"\"http_expect\":" "204,"
"\"http_fail_redirect\": true"
"}}"
"]}"
;

View file

@ -300,7 +300,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584
CONFIG_ESP_MAIN_TASK_STACK_SIZE=6584
CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048

View file

@ -88,7 +88,7 @@
#define CONFIG_ESP_ERR_TO_NAME_LOOKUP 1
#define CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE 32
#define CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE 2304
#define CONFIG_ESP_MAIN_TASK_STACK_SIZE 3584
#define CONFIG_ESP_MAIN_TASK_STACK_SIZE 6584
#define CONFIG_ESP_IPC_TASK_STACK_SIZE 1024
#define CONFIG_ESP_IPC_USES_CALLERS_PRIORITY 1
#define CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE 2048