1d4afb5ceSopenharmony_ci/*
2d4afb5ceSopenharmony_ci * ws protocol handler plugin for "dumb increment"
3d4afb5ceSopenharmony_ci *
4d4afb5ceSopenharmony_ci * Written in 2010-2019 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 * The person who associated a work with this deed has dedicated
10d4afb5ceSopenharmony_ci * the work to the public domain by waiving all of his or her rights
11d4afb5ceSopenharmony_ci * to the work worldwide under copyright law, including all related
12d4afb5ceSopenharmony_ci * and neighboring rights, to the extent allowed by law. You can copy,
13d4afb5ceSopenharmony_ci * modify, distribute and perform the work, even for commercial purposes,
14d4afb5ceSopenharmony_ci * all without asking permission.
15d4afb5ceSopenharmony_ci *
16d4afb5ceSopenharmony_ci * These test plugins are intended to be adapted for use in your code, which
17d4afb5ceSopenharmony_ci * may be proprietary.  So unlike the library itself, they are licensed
18d4afb5ceSopenharmony_ci * Public Domain.
19d4afb5ceSopenharmony_ci *
20d4afb5ceSopenharmony_ci * This is a copy of dumb_increment adapted slightly to serve as the
21d4afb5ceSopenharmony_ci * "example-standalone-protocol", to show how to build protocol plugins
22d4afb5ceSopenharmony_ci * outside the library easily.
23d4afb5ceSopenharmony_ci */
24d4afb5ceSopenharmony_ci
25d4afb5ceSopenharmony_ci#if !defined (LWS_PLUGIN_STATIC)
26d4afb5ceSopenharmony_ci#if !defined(LWS_DLL)
27d4afb5ceSopenharmony_ci#define LWS_DLL
28d4afb5ceSopenharmony_ci#endif
29d4afb5ceSopenharmony_ci#if !defined(LWS_INTERNAL)
30d4afb5ceSopenharmony_ci#define LWS_INTERNAL
31d4afb5ceSopenharmony_ci#endif
32d4afb5ceSopenharmony_ci#include <libwebsockets.h>
33d4afb5ceSopenharmony_ci#endif
34d4afb5ceSopenharmony_ci
35d4afb5ceSopenharmony_ci#include <string.h>
36d4afb5ceSopenharmony_ci
37d4afb5ceSopenharmony_cistruct per_vhost_data__dumb_increment {
38d4afb5ceSopenharmony_ci	uv_timer_t timeout_watcher;
39d4afb5ceSopenharmony_ci	struct lws_context *context;
40d4afb5ceSopenharmony_ci	struct lws_vhost *vhost;
41d4afb5ceSopenharmony_ci	const struct lws_protocols *protocol;
42d4afb5ceSopenharmony_ci};
43d4afb5ceSopenharmony_ci
44d4afb5ceSopenharmony_cistruct per_session_data__dumb_increment {
45d4afb5ceSopenharmony_ci	int number;
46d4afb5ceSopenharmony_ci};
47d4afb5ceSopenharmony_ci
48d4afb5ceSopenharmony_cistatic void
49d4afb5ceSopenharmony_ciuv_timeout_cb_dumb_increment(uv_timer_t *w
50d4afb5ceSopenharmony_ci#if UV_VERSION_MAJOR == 0
51d4afb5ceSopenharmony_ci		, int status
52d4afb5ceSopenharmony_ci#endif
53d4afb5ceSopenharmony_ci)
54d4afb5ceSopenharmony_ci{
55d4afb5ceSopenharmony_ci	struct per_vhost_data__dumb_increment *vhd = lws_container_of(w,
56d4afb5ceSopenharmony_ci			struct per_vhost_data__dumb_increment, timeout_watcher);
57d4afb5ceSopenharmony_ci	lws_callback_on_writable_all_protocol_vhost(vhd->vhost, vhd->protocol);
58d4afb5ceSopenharmony_ci}
59d4afb5ceSopenharmony_ci
60d4afb5ceSopenharmony_cistatic int
61d4afb5ceSopenharmony_cicallback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
62d4afb5ceSopenharmony_ci			void *user, void *in, size_t len)
63d4afb5ceSopenharmony_ci{
64d4afb5ceSopenharmony_ci	struct per_session_data__dumb_increment *pss =
65d4afb5ceSopenharmony_ci			(struct per_session_data__dumb_increment *)user;
66d4afb5ceSopenharmony_ci	struct per_vhost_data__dumb_increment *vhd =
67d4afb5ceSopenharmony_ci			(struct per_vhost_data__dumb_increment *)
68d4afb5ceSopenharmony_ci			lws_protocol_vh_priv_get(lws_get_vhost(wsi),
69d4afb5ceSopenharmony_ci					lws_get_protocol(wsi));
70d4afb5ceSopenharmony_ci	unsigned char buf[LWS_PRE + 512];
71d4afb5ceSopenharmony_ci	unsigned char *p = &buf[LWS_PRE];
72d4afb5ceSopenharmony_ci	int n, m;
73d4afb5ceSopenharmony_ci
74d4afb5ceSopenharmony_ci	switch (reason) {
75d4afb5ceSopenharmony_ci	case LWS_CALLBACK_PROTOCOL_INIT:
76d4afb5ceSopenharmony_ci		vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
77d4afb5ceSopenharmony_ci				lws_get_protocol(wsi),
78d4afb5ceSopenharmony_ci				sizeof(struct per_vhost_data__dumb_increment));
79d4afb5ceSopenharmony_ci		vhd->context = lws_get_context(wsi);
80d4afb5ceSopenharmony_ci		vhd->protocol = lws_get_protocol(wsi);
81d4afb5ceSopenharmony_ci		vhd->vhost = lws_get_vhost(wsi);
82d4afb5ceSopenharmony_ci		uv_timer_init(lws_uv_getloop(vhd->context, 0),
83d4afb5ceSopenharmony_ci			      &vhd->timeout_watcher);
84d4afb5ceSopenharmony_ci		uv_timer_start(&vhd->timeout_watcher,
85d4afb5ceSopenharmony_ci			       uv_timeout_cb_dumb_increment, 50, 50);
86d4afb5ceSopenharmony_ci		break;
87d4afb5ceSopenharmony_ci
88d4afb5ceSopenharmony_ci	case LWS_CALLBACK_PROTOCOL_DESTROY:
89d4afb5ceSopenharmony_ci		if (!vhd)
90d4afb5ceSopenharmony_ci			break;
91d4afb5ceSopenharmony_ci		uv_timer_stop(&vhd->timeout_watcher);
92d4afb5ceSopenharmony_ci		break;
93d4afb5ceSopenharmony_ci
94d4afb5ceSopenharmony_ci	case LWS_CALLBACK_ESTABLISHED:
95d4afb5ceSopenharmony_ci		pss->number = 0;
96d4afb5ceSopenharmony_ci		break;
97d4afb5ceSopenharmony_ci
98d4afb5ceSopenharmony_ci	case LWS_CALLBACK_SERVER_WRITEABLE:
99d4afb5ceSopenharmony_ci		n = sprintf((char *)p, "%d", pss->number++);
100d4afb5ceSopenharmony_ci		m = lws_write(wsi, p, n, LWS_WRITE_TEXT);
101d4afb5ceSopenharmony_ci		if (m < n) {
102d4afb5ceSopenharmony_ci			lwsl_err("ERROR %d writing to di socket\n", n);
103d4afb5ceSopenharmony_ci			return -1;
104d4afb5ceSopenharmony_ci		}
105d4afb5ceSopenharmony_ci		break;
106d4afb5ceSopenharmony_ci
107d4afb5ceSopenharmony_ci	case LWS_CALLBACK_RECEIVE:
108d4afb5ceSopenharmony_ci		if (len < 6)
109d4afb5ceSopenharmony_ci			break;
110d4afb5ceSopenharmony_ci		if (strcmp((const char *)in, "reset\n") == 0)
111d4afb5ceSopenharmony_ci			pss->number = 0;
112d4afb5ceSopenharmony_ci		if (strcmp((const char *)in, "closeme\n") == 0) {
113d4afb5ceSopenharmony_ci			lwsl_notice("dumb_inc: closing as requested\n");
114d4afb5ceSopenharmony_ci			lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY,
115d4afb5ceSopenharmony_ci					 (unsigned char *)"seeya", 5);
116d4afb5ceSopenharmony_ci			return -1;
117d4afb5ceSopenharmony_ci		}
118d4afb5ceSopenharmony_ci		break;
119d4afb5ceSopenharmony_ci
120d4afb5ceSopenharmony_ci	default:
121d4afb5ceSopenharmony_ci		break;
122d4afb5ceSopenharmony_ci	}
123d4afb5ceSopenharmony_ci
124d4afb5ceSopenharmony_ci	return 0;
125d4afb5ceSopenharmony_ci}
126d4afb5ceSopenharmony_ci
127d4afb5ceSopenharmony_cistatic const struct lws_protocols protocols[] = {
128d4afb5ceSopenharmony_ci	{
129d4afb5ceSopenharmony_ci		"example-standalone-protocol",
130d4afb5ceSopenharmony_ci		callback_dumb_increment,
131d4afb5ceSopenharmony_ci		sizeof(struct per_session_data__dumb_increment),
132d4afb5ceSopenharmony_ci		10, /* rx buf size must be >= permessage-deflate rx size */
133d4afb5ceSopenharmony_ci	},
134d4afb5ceSopenharmony_ci};
135d4afb5ceSopenharmony_ci
136d4afb5ceSopenharmony_ciLWS_VISIBLE const lws_plugin_protocol_t protocol_example_standalone = {
137d4afb5ceSopenharmony_ci	.hdr = {
138d4afb5ceSopenharmony_ci		"standalone",
139d4afb5ceSopenharmony_ci		"lws_protocol_plugin",
140d4afb5ceSopenharmony_ci		LWS_BUILD_HASH,
141d4afb5ceSopenharmony_ci		LWS_PLUGIN_API_MAGIC
142d4afb5ceSopenharmony_ci	},
143d4afb5ceSopenharmony_ci
144d4afb5ceSopenharmony_ci	.protocols = protocols,
145d4afb5ceSopenharmony_ci	.count_protocols = LWS_ARRAY_SIZE(protocols),
146d4afb5ceSopenharmony_ci	.extensions = NULL,
147d4afb5ceSopenharmony_ci	.count_extensions = 0,
148d4afb5ceSopenharmony_ci};
149