1/*
2 * lws-minimal-secure-streams-server
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
10#include <libwebsockets.h>
11#include <assert.h>
12
13extern int interrupted, bad;
14
15typedef struct myss {
16	struct lws_ss_handle 		*ss;
17	void				*opaque_data;
18	/* ... application specific state ... */
19
20	lws_sorted_usec_list_t		sul;
21	int				count;
22	char				upgraded;
23
24} myss_srv_t;
25
26/*
27 * This is the Secure Streams Server RX and TX
28 */
29
30static lws_ss_state_return_t
31myss_raw_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
32{
33//	myss_srv_t *m = (myss_srv_t *)userobj;
34
35	lwsl_user("%s: len %d, flags: %d\n", __func__, (int)len, flags);
36	lwsl_hexdump_info(buf, len);
37
38	/*
39	 * If we received the whole message, for our example it means
40	 * we are done.
41	 */
42	if (flags & LWSSS_FLAG_EOM) {
43		bad = 0;
44		interrupted = 1;
45	}
46
47	return 0;
48}
49
50/* this is the callback that mediates sending the incrementing number */
51
52static void
53spam_sul_cb(struct lws_sorted_usec_list *sul)
54{
55	myss_srv_t *m = lws_container_of(sul, myss_srv_t, sul);
56
57	if (!lws_ss_request_tx(m->ss))
58		lws_sul_schedule(lws_ss_get_context(m->ss), 0, &m->sul, spam_sul_cb,
59			 100 * LWS_US_PER_MS);
60}
61
62static lws_ss_state_return_t
63myss_raw_tx(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf, size_t *len,
64	int *flags)
65{
66	myss_srv_t *m = (myss_srv_t *)userobj;
67
68	*flags = LWSSS_FLAG_SOM | LWSSS_FLAG_EOM;
69
70	*len = (unsigned int)lws_snprintf((char *)buf, *len, "hello from raw %d\n", m->count++);
71
72	lws_sul_schedule(lws_ss_get_context(m->ss), 0, &m->sul, spam_sul_cb,
73			 100 * LWS_US_PER_MS);
74
75	return 0;
76}
77
78static lws_ss_state_return_t
79myss_raw_state(void *userobj, void *sh, lws_ss_constate_t state,
80	   lws_ss_tx_ordinal_t ack)
81{
82	myss_srv_t *m = (myss_srv_t *)userobj;
83
84	lwsl_user("%s: %p %s, ord 0x%x\n", __func__, m->ss,
85		  lws_ss_state_name((int)state), (unsigned int)ack);
86
87	switch (state) {
88	case LWSSSCS_DISCONNECTED:
89		lws_sul_cancel(&m->sul);
90		break;
91	case LWSSSCS_CONNECTED:
92		return lws_ss_request_tx(m->ss);
93
94	default:
95		break;
96	}
97
98	return 0;
99}
100
101const lws_ss_info_t ssi_server = {
102	.handle_offset			= offsetof(myss_srv_t, ss),
103	.opaque_user_data_offset	= offsetof(myss_srv_t, opaque_data),
104	.streamtype			= "myrawserver",
105	.rx				= myss_raw_rx,
106	.tx				= myss_raw_tx,
107	.state				= myss_raw_state,
108	.user_alloc			= sizeof(myss_srv_t),
109};
110