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