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