3 #include <libwebsockets.h>
20 #define JSON_STRING "{" \
21 "\"type\": \"rfid\"," \
26 static const struct lws_http_mount mount = {
27 /* .mount_next */ NULL, /* linked-list "next" */
28 /* .mountpoint */ "/", /* mountpoint URL */
29 /* .origin */ "/usr/share/mt-server", /* serve from dir */
30 /* .def */ "index.html", /* default filename */
33 /* .extra_mimetypes */ NULL,
34 /* .interpret */ NULL,
36 /* .cache_max_age */ 0,
38 /* .cache_reusable */ 0,
39 /* .cache_revalidate */ 0,
40 /* .cache_intermediaries */ 0,
41 /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */
42 /* .mountpoint_len */ 1, /* char count */
43 /* .basic_auth_login_file */ NULL,
46 typedef struct per_vhost_data__dumb_increment {
47 struct lws_context *context;
48 struct lws_vhost *vhost;
49 const struct lws_protocols *protocol;
50 } per_vhost_data__dumb_increment;
52 typedef struct per_session_data__dumb_increment {
58 } per_session_data__dumb_increment;
60 typedef struct user_data {
64 static char line[512];
66 static int callback_dumb_increment(struct lws *wsi,
67 enum lws_callback_reasons reason,
68 void *user, void *in, size_t len)
70 per_session_data__dumb_increment *pss =
71 (per_session_data__dumb_increment *)user;
72 per_vhost_data__dumb_increment *vhd =
73 (per_vhost_data__dumb_increment *)
74 lws_protocol_vh_priv_get(lws_get_vhost(wsi), lws_get_protocol(wsi));
76 struct lws_context *context = lws_get_context(wsi);
77 user_data *data = (user_data *)lws_context_user(context);
80 unsigned char buf[LWS_PRE + 512];
81 unsigned char *p = &buf[LWS_PRE];
85 case LWS_CALLBACK_PROTOCOL_INIT:
86 vhd = lws_protocol_vh_priv_zalloc(
88 lws_get_protocol(wsi),
89 sizeof(struct per_vhost_data__dumb_increment)
91 vhd->context = lws_get_context(wsi);
92 vhd->protocol = lws_get_protocol(wsi);
93 vhd->vhost = lws_get_vhost(wsi);
96 case LWS_CALLBACK_PROTOCOL_DESTROY:
102 case LWS_CALLBACK_ESTABLISHED:
106 case LWS_CALLBACK_SERVER_WRITEABLE:
107 n = sprintf((char *)p, JSON_STRING, uids[pss->number % 10], pss->number);
110 m = lws_write(wsi, line, n, LWS_WRITE_TEXT);
112 printf("ERROR %d writing to di socket\n", n);
117 case LWS_CALLBACK_RECEIVE:
121 if (strcmp((const char *)in, "reset\n") == 0) {
124 if (strcmp((const char *)in, "close\n") == 0) {
125 printf("dumb_inc: closing as requested\n");
126 lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY,
127 (unsigned char *)"seeya", 5);
139 enum demo_protocols {
143 PROTOCOL_DUMB_INCREMENT,
151 /* list of supported protocols and callbacks */
153 static struct lws_protocols protocols[] = {
154 /* first protocol must always be HTTP handler */
155 {"http", lws_callback_http_dummy, 0, 0},
157 "dumb-increment-protocol",
158 callback_dumb_increment,
159 sizeof(struct per_session_data__dumb_increment),
160 128, /* rx buf size must be >= permessage-deflate rx size
161 * dumb-increment only sends very small packets, so we set
162 * this accordingly. If your protocol will send bigger
163 * things, adjust this to match */
165 {NULL, NULL, 0, 0} /* terminator */
168 struct lws_context *context;
170 static void ev_timeout_cb(EV_P_ ev_timer *w, int revents)
172 lws_callback_on_writable_all_protocol(context,
173 &protocols[PROTOCOL_DUMB_INCREMENT]);
176 static void signal_cb(EV_P_ ev_signal *w, int revents)
178 fprintf(stderr, "signal caught, terminating\n");
182 ev_break(loop, EVBREAK_ALL);
185 signal(SIGABRT, SIG_DFL);
193 int server_init(void *user)
195 struct lws_context_creation_info info;
197 protocols[PROTOCOL_DUMB_INCREMENT].user = (void *)line;
199 memset(&info, 0, sizeof info);
201 info.mounts = &mount;
202 info.protocols = protocols;
203 info.max_http_header_pool = 1;
204 info.options |= LWS_SERVER_OPTION_LIBEV;
207 context = lws_create_context(&info);
209 fprintf(stderr, "lws_create_context failed\n");
218 static void stdin_cb(EV_P_ ev_io *w, int revents)
222 read(w->fd, &line[pos++], 1);
224 if (line[pos-1] == '\n') {
228 lws_callback_on_writable_all_protocol(context,
229 &protocols[PROTOCOL_DUMB_INCREMENT]);
234 int main(int argc, const char **argv)
236 int sigs[] = { SIGINT, SIGKILL, SIGTERM, SIGSEGV, SIGFPE };
237 struct ev_signal signals[ARRAY_SIZE(sigs)];
239 struct ev_loop *loop = ev_default_loop(0);
240 ev_timer timeout_watcher;
242 for (int n = 0; n < ARRAY_SIZE(sigs); n++) {
243 ev_init(&signals[n], signal_cb);
244 ev_signal_set(&signals[n], sigs[n]);
245 ev_signal_start(loop, &signals[n]);
248 if (server_init(NULL) == -1) {
251 lws_ev_initloop(context, loop, 0);
253 ev_io_init(&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
254 ev_io_start(loop, &stdin_watcher);
256 ev_timer_init(&timeout_watcher, ev_timeout_cb, 1, 1);
257 //ev_timer_start(loop, &timeout_watcher);
261 lws_context_destroy(context);