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