| /* |
| * lws-minimal-esp32 |
| * |
| * 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. |
| * |
| * 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 |
| #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_context *context; |
| 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; |
| |
| lws_sorted_usec_list_t sul_pass; |
| |
| extern int init_plat_devices(struct lws_context *); |
| |
| static const uint8_t logo[] = { |
| #include "cat-565.h" |
| }; |
| |
| #if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) |
| #include "static-policy.h" |
| #else |
| #include "policy.h" |
| #endif |
| |
| static uint8_t flip; |
| |
| |
| typedef struct myss { |
| struct lws_ss_handle *ss; |
| void *opaque_data; |
| /* ... application specific state ... */ |
| |
| size_t amount; |
| |
| } myss_t; |
| |
| /* |
| * When we're actually happy we passed, we schedule the actual pass |
| * string to happen a few seconds later, so we can observe what the |
| * code did after the pass. |
| */ |
| |
| static void |
| completion_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"); |
| } |
| |
| 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. |
| * |
| * Howevere we want to record what happened after we received |
| * the last bit so we can see anything unexpected coming. So |
| * wait a couple of seconds before sending the PASS magic. |
| */ |
| |
| lwsl_notice("%s: received %u bytes, passing in 10s\n", |
| __func__, (unsigned int)m->amount); |
| |
| lws_sul_schedule(context, 0, &sul_pass, completion_sul_cb, |
| 10 * LWS_US_PER_SEC); |
| |
| return LWSSSSRET_DESTROY_ME; |
| } |
| |
| 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, |
| &lws_pwmseq_sine_endless_slow, |
| &lws_pwmseq_sine_endless_fast, |
| }; |
| |
| static int |
| 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") && |
| !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); |
| |
| 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; |
| } |
| |
| void |
| app_main(void) |
| { |
| struct lws_context_creation_info *info; |
| |
| lws_set_log_level(1024 | 15, NULL); |
| |
| lws_netdev_plat_init(); |
| lws_netdev_plat_wifi_init(); |
| |
| info = malloc(sizeof(*info)); |
| if (!info) |
| goto spin; |
| |
| memset(info, 0, sizeof(*info)); |
| |
| lwsl_notice("LWS test for Espressif ESP32 WROVER KIT\n"); |
| |
| #if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) |
| info->pss_policies_json = ss_policy; |
| #else |
| info->pss_policies = &_ss_static_policy_entry; |
| #endif |
| 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); |
| if (!context) { |
| lwsl_err("lws init failed\n"); |
| goto spin; |
| } |
| |
| /* |
| * We don't need this after context creation... things it pointed to |
| * still need to exist though since the context copied the pointers. |
| */ |
| |
| free(info); |
| |
| /* devices and init are in devices.c */ |
| |
| if (init_plat_devices(context)) |
| goto spin; |
| |
| /* put the cat picture up there and enable the backlight */ |
| |
| lds.disp->blit(lds.disp, logo, 0, 0, 320, 240); |
| lws_display_state_active(&lds); |
| |
| /* the lws event loop */ |
| |
| do { |
| taskYIELD(); |
| } while (lws_service(context, 0) >= 0); |
| |
| lwsl_notice("%s: exited event loop\n", __func__); |
| |
| |
| spin: |
| vTaskDelay(10); |
| taskYIELD(); |
| goto spin; |
| } |