1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * lws-minimal-esp32 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Written in 2010-2020 by Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * This file is made available under the Creative Commons CC0 1.0 7d4afb5ceSopenharmony_ci * Universal Public Domain Dedication. 8d4afb5ceSopenharmony_ci * 9d4afb5ceSopenharmony_ci * Based on espressif Public Domain sample 10d4afb5ceSopenharmony_ci */ 11d4afb5ceSopenharmony_ci 12d4afb5ceSopenharmony_ci#define LWIP_PROVIDE_ERRNO 1 13d4afb5ceSopenharmony_ci#define _ESP_PLATFORM_ERRNO_H_ 14d4afb5ceSopenharmony_ci 15d4afb5ceSopenharmony_ci#include <stdio.h> 16d4afb5ceSopenharmony_ci#include "sdkconfig.h" 17d4afb5ceSopenharmony_ci#include "freertos/FreeRTOS.h" 18d4afb5ceSopenharmony_ci#include "freertos/task.h" 19d4afb5ceSopenharmony_ci 20d4afb5ceSopenharmony_ci#include <driver/gpio.h> 21d4afb5ceSopenharmony_ci 22d4afb5ceSopenharmony_ci#include <libwebsockets.h> 23d4afb5ceSopenharmony_ci 24d4afb5ceSopenharmony_cistruct lws_context *context; 25d4afb5ceSopenharmony_ciextern struct lws_led_state *lls; 26d4afb5ceSopenharmony_ciextern lws_display_state_t lds; 27d4afb5ceSopenharmony_ciextern lws_netdev_instance_wifi_t *wnd; 28d4afb5ceSopenharmony_ci 29d4afb5ceSopenharmony_ciextern int init_plat_devices(struct lws_context *); 30d4afb5ceSopenharmony_ci 31d4afb5ceSopenharmony_ci#include "policy.h" 32d4afb5ceSopenharmony_ci 33d4afb5ceSopenharmony_cistatic uint8_t flip; 34d4afb5ceSopenharmony_ci 35d4afb5ceSopenharmony_citypedef struct myss { 36d4afb5ceSopenharmony_ci struct lws_ss_handle *ss; 37d4afb5ceSopenharmony_ci void *opaque_data; 38d4afb5ceSopenharmony_ci /* ... application specific state ... */ 39d4afb5ceSopenharmony_ci 40d4afb5ceSopenharmony_ci size_t amount; 41d4afb5ceSopenharmony_ci 42d4afb5ceSopenharmony_ci} myss_t; 43d4afb5ceSopenharmony_ci 44d4afb5ceSopenharmony_cistatic int 45d4afb5ceSopenharmony_cimyss_rx(void *userobj, const uint8_t *buf, size_t len, int flags) 46d4afb5ceSopenharmony_ci{ 47d4afb5ceSopenharmony_ci myss_t *m = (myss_t *)userobj; 48d4afb5ceSopenharmony_ci 49d4afb5ceSopenharmony_ci lwsl_user("%s: len %d, flags: %d\n", __func__, (int)len, flags); 50d4afb5ceSopenharmony_ci// lwsl_hexdump_info(buf, len); 51d4afb5ceSopenharmony_ci m->amount += len; 52d4afb5ceSopenharmony_ci 53d4afb5ceSopenharmony_ci if (flags & LWSSS_FLAG_EOM) { 54d4afb5ceSopenharmony_ci 55d4afb5ceSopenharmony_ci /* 56d4afb5ceSopenharmony_ci * If we received the whole message, for our example it means 57d4afb5ceSopenharmony_ci * we are done. 58d4afb5ceSopenharmony_ci */ 59d4afb5ceSopenharmony_ci 60d4afb5ceSopenharmony_ci lwsl_notice("%s: received %u bytes\n", __func__, 61d4afb5ceSopenharmony_ci (unsigned int)m->amount); 62d4afb5ceSopenharmony_ci 63d4afb5ceSopenharmony_ci /* 64d4afb5ceSopenharmony_ci * In CI, we use sai-expect to look for this 65d4afb5ceSopenharmony_ci * string for success 66d4afb5ceSopenharmony_ci */ 67d4afb5ceSopenharmony_ci 68d4afb5ceSopenharmony_ci lwsl_notice("Completed: PASS\n"); 69d4afb5ceSopenharmony_ci } 70d4afb5ceSopenharmony_ci 71d4afb5ceSopenharmony_ci return 0; 72d4afb5ceSopenharmony_ci} 73d4afb5ceSopenharmony_ci 74d4afb5ceSopenharmony_cistatic int 75d4afb5ceSopenharmony_cimyss_state(void *userobj, void *sh, lws_ss_constate_t state, 76d4afb5ceSopenharmony_ci lws_ss_tx_ordinal_t ack) 77d4afb5ceSopenharmony_ci{ 78d4afb5ceSopenharmony_ci myss_t *m = (myss_t *)userobj; 79d4afb5ceSopenharmony_ci 80d4afb5ceSopenharmony_ci lwsl_user("%s: %s, ord 0x%x\n", __func__, lws_ss_state_name(state), 81d4afb5ceSopenharmony_ci (unsigned int)ack); 82d4afb5ceSopenharmony_ci 83d4afb5ceSopenharmony_ci switch (state) { 84d4afb5ceSopenharmony_ci case LWSSSCS_CREATING: 85d4afb5ceSopenharmony_ci if (lws_ss_client_connect(m->ss)) 86d4afb5ceSopenharmony_ci lwsl_err("%s: connection failed\n", __func__); 87d4afb5ceSopenharmony_ci break; 88d4afb5ceSopenharmony_ci default: 89d4afb5ceSopenharmony_ci break; 90d4afb5ceSopenharmony_ci } 91d4afb5ceSopenharmony_ci 92d4afb5ceSopenharmony_ci return 0; 93d4afb5ceSopenharmony_ci} 94d4afb5ceSopenharmony_ci 95d4afb5ceSopenharmony_cistatic const lws_ss_info_t ssi = { 96d4afb5ceSopenharmony_ci .handle_offset = offsetof(myss_t, ss), 97d4afb5ceSopenharmony_ci .opaque_user_data_offset = offsetof(myss_t, opaque_data), 98d4afb5ceSopenharmony_ci .rx = myss_rx, 99d4afb5ceSopenharmony_ci .state = myss_state, 100d4afb5ceSopenharmony_ci .user_alloc = sizeof(myss_t), 101d4afb5ceSopenharmony_ci .streamtype = "test_stream", 102d4afb5ceSopenharmony_ci}; 103d4afb5ceSopenharmony_ci 104d4afb5ceSopenharmony_cistatic const lws_led_sequence_def_t *seqs[] = { 105d4afb5ceSopenharmony_ci &lws_pwmseq_static_on, 106d4afb5ceSopenharmony_ci &lws_pwmseq_static_off, 107d4afb5ceSopenharmony_ci &lws_pwmseq_sine_endless_slow, 108d4afb5ceSopenharmony_ci &lws_pwmseq_sine_endless_fast, 109d4afb5ceSopenharmony_ci}; 110d4afb5ceSopenharmony_ci 111d4afb5ceSopenharmony_cistatic int 112d4afb5ceSopenharmony_cismd_cb(void *opaque, lws_smd_class_t _class, lws_usec_t timestamp, void *buf, 113d4afb5ceSopenharmony_ci size_t len) 114d4afb5ceSopenharmony_ci{ 115d4afb5ceSopenharmony_ci 116d4afb5ceSopenharmony_ci if (!lws_json_simple_strcmp(buf, len, "\"src\":", "bc/user") && 117d4afb5ceSopenharmony_ci !lws_json_simple_strcmp(buf, len, "\"event\":", "click")) { 118d4afb5ceSopenharmony_ci lws_led_transition(lls, "alert", seqs[flip & 3], 119d4afb5ceSopenharmony_ci &lws_pwmseq_linear_wipe); 120d4afb5ceSopenharmony_ci flip++; 121d4afb5ceSopenharmony_ci } 122d4afb5ceSopenharmony_ci 123d4afb5ceSopenharmony_ci lwsl_hexdump_notice(buf, len); 124d4afb5ceSopenharmony_ci 125d4afb5ceSopenharmony_ci if ((_class & LWSSMDCL_SYSTEM_STATE) && 126d4afb5ceSopenharmony_ci !lws_json_simple_strcmp(buf, len, "\"state\":", "OPERATIONAL")) { 127d4afb5ceSopenharmony_ci 128d4afb5ceSopenharmony_ci /* create the secure stream */ 129d4afb5ceSopenharmony_ci 130d4afb5ceSopenharmony_ci lwsl_notice("%s: creating test secure stream\n", __func__); 131d4afb5ceSopenharmony_ci 132d4afb5ceSopenharmony_ci if (lws_ss_create(context, 0, &ssi, NULL, NULL, NULL, NULL)) { 133d4afb5ceSopenharmony_ci lwsl_err("%s: failed to create secure stream\n", 134d4afb5ceSopenharmony_ci __func__); 135d4afb5ceSopenharmony_ci return -1; 136d4afb5ceSopenharmony_ci } 137d4afb5ceSopenharmony_ci } 138d4afb5ceSopenharmony_ci 139d4afb5ceSopenharmony_ci if (_class & LWSSMDCL_INTERACTION) 140d4afb5ceSopenharmony_ci /* 141d4afb5ceSopenharmony_ci * Any kind of user interaction brings the display back up and 142d4afb5ceSopenharmony_ci * resets the dimming / blanking timers 143d4afb5ceSopenharmony_ci */ 144d4afb5ceSopenharmony_ci lws_display_state_active(&lds); 145d4afb5ceSopenharmony_ci 146d4afb5ceSopenharmony_ci return 0; 147d4afb5ceSopenharmony_ci} 148d4afb5ceSopenharmony_ci 149d4afb5ceSopenharmony_civoid 150d4afb5ceSopenharmony_ciapp_main(void) 151d4afb5ceSopenharmony_ci{ 152d4afb5ceSopenharmony_ci struct lws_context_creation_info *info; 153d4afb5ceSopenharmony_ci 154d4afb5ceSopenharmony_ci lws_set_log_level(1024 | 7, NULL); 155d4afb5ceSopenharmony_ci 156d4afb5ceSopenharmony_ci lws_netdev_plat_init(); 157d4afb5ceSopenharmony_ci lws_netdev_plat_wifi_init(); 158d4afb5ceSopenharmony_ci 159d4afb5ceSopenharmony_ci info = malloc(sizeof(*info)); 160d4afb5ceSopenharmony_ci if (!info) 161d4afb5ceSopenharmony_ci goto spin; 162d4afb5ceSopenharmony_ci 163d4afb5ceSopenharmony_ci memset(info, 0, sizeof(*info)); 164d4afb5ceSopenharmony_ci 165d4afb5ceSopenharmony_ci lwsl_notice("LWS test for ESP32-C3 Dev Board\n"); 166d4afb5ceSopenharmony_ci 167d4afb5ceSopenharmony_ci info->pss_policies_json = ss_policy; 168d4afb5ceSopenharmony_ci info->options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS | 169d4afb5ceSopenharmony_ci LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; 170d4afb5ceSopenharmony_ci info->port = CONTEXT_PORT_NO_LISTEN; 171d4afb5ceSopenharmony_ci info->early_smd_cb = smd_cb; 172d4afb5ceSopenharmony_ci info->early_smd_class_filter = LWSSMDCL_INTERACTION | 173d4afb5ceSopenharmony_ci LWSSMDCL_SYSTEM_STATE | 174d4afb5ceSopenharmony_ci LWSSMDCL_NETWORK; 175d4afb5ceSopenharmony_ci 176d4afb5ceSopenharmony_ci context = lws_create_context(info); 177d4afb5ceSopenharmony_ci if (!context) { 178d4afb5ceSopenharmony_ci lwsl_err("lws init failed\n"); 179d4afb5ceSopenharmony_ci return; 180d4afb5ceSopenharmony_ci } 181d4afb5ceSopenharmony_ci 182d4afb5ceSopenharmony_ci /* 183d4afb5ceSopenharmony_ci * We don't need this after context creation... things it pointed to 184d4afb5ceSopenharmony_ci * still need to exist though since the context copied the pointers. 185d4afb5ceSopenharmony_ci */ 186d4afb5ceSopenharmony_ci 187d4afb5ceSopenharmony_ci free(info); 188d4afb5ceSopenharmony_ci 189d4afb5ceSopenharmony_ci /* devices and init are in devices.c */ 190d4afb5ceSopenharmony_ci 191d4afb5ceSopenharmony_ci if (init_plat_devices(context)) 192d4afb5ceSopenharmony_ci goto spin; 193d4afb5ceSopenharmony_ci 194d4afb5ceSopenharmony_ci 195d4afb5ceSopenharmony_ci /* the lws event loop */ 196d4afb5ceSopenharmony_ci 197d4afb5ceSopenharmony_ci do { 198d4afb5ceSopenharmony_ci taskYIELD(); 199d4afb5ceSopenharmony_ci } while (lws_service(context, 0) >= 0); 200d4afb5ceSopenharmony_ci 201d4afb5ceSopenharmony_ci 202d4afb5ceSopenharmony_cispin: 203d4afb5ceSopenharmony_ci vTaskDelay(10); 204d4afb5ceSopenharmony_ci taskYIELD(); 205d4afb5ceSopenharmony_ci goto spin; 206d4afb5ceSopenharmony_ci} 207