]> rtime.felk.cvut.cz Git - coffee/mt-apps.git/blob - mt_server.c
remove timer remnants
[coffee/mt-apps.git] / mt_server.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "mt_server.h"
6 #include "ev_signal_exit.h"
7
8 #define JSON_EMPTY "{\"type\":\"empty\"}"
9
10 static const struct lws_http_mount mount = {
11     /* .mount_next */            NULL,         /* linked-list "next" */
12     /* .mountpoint */            "/",          /* mountpoint URL */
13     /* .origin */                "/usr/share/mt-server", /* serve from dir */
14     /* .def */                   "index.html", /* default filename */
15     /* .protocol */              NULL,
16     /* .cgienv */                NULL,
17     /* .extra_mimetypes */       NULL,
18     /* .interpret */             NULL,
19     /* .cgi_timeout */           0,
20     /* .cache_max_age */         0,
21     /* .auth_mask */             0,
22     /* .cache_reusable */        0,
23     /* .cache_revalidate */      0,
24     /* .cache_intermediaries */  0,
25     /* .origin_protocol */       LWSMPRO_FILE, /* files in a dir */
26     /* .mountpoint_len */        1,            /* char count */
27     /* .basic_auth_login_file */ NULL,
28 };
29
30 typedef struct per_vhost_data__dumb_increment {
31     struct lws_context *context;
32     struct lws_vhost *vhost;
33     const struct lws_protocols *protocol;
34 } per_vhost_data__dumb_increment;
35
36 typedef struct per_session_data__dumb_increment {
37     uint8_t card_type;
38     uint8_t sak;
39     uint8_t uid_size;
40     char *uid;
41     int number;
42 } per_session_data__dumb_increment;
43
44 enum protocols {
45     PROTOCOL_HTTP = 0, // always first
46     PROTOCOL_MERICA_TERMINAL
47 };
48
49 static int callback_merica_terminal(struct lws *wsi,
50                                     enum lws_callback_reasons reason,
51                                     void *user, void *in, size_t len);
52
53 // list of supported protocols and callbacks
54 static struct lws_protocols protocols[] = {
55     /* first protocol must always be HTTP handler */
56     {"http", lws_callback_http_dummy, 0, 0},
57     {
58         "dumb-increment-protocol",
59         callback_merica_terminal,
60         sizeof(struct per_session_data__dumb_increment),
61         128, /* rx buf size must be >= permessage-deflate rx size
62              * dumb-increment only sends very small packets, so we set
63              * this accordingly.  If your protocol will send bigger
64              * things, adjust this to match */
65     },
66     {NULL, NULL, 0, 0} /* terminator */
67 };
68
69 static int callback_merica_terminal(struct lws *wsi,
70                                     enum lws_callback_reasons reason,
71                                     void *user, void *in, size_t len)
72 {
73     struct lws_vhost *vhost = lws_get_vhost(wsi);
74     const struct lws_protocols *prot = lws_get_protocol(wsi);
75     per_session_data__dumb_increment *pss =
76         (per_session_data__dumb_increment *)user;
77     per_vhost_data__dumb_increment *vhd =
78         (per_vhost_data__dumb_increment *)
79         lws_protocol_vh_priv_get(vhost, prot);
80
81     int n, m;
82
83     char *line = (char *)prot->user;
84
85     switch (reason) {
86         case LWS_CALLBACK_PROTOCOL_INIT:
87             vhd = lws_protocol_vh_priv_zalloc(
88                       vhost, prot,
89                       sizeof(struct per_vhost_data__dumb_increment)
90                   );
91             vhd->context = lws_get_context(wsi);
92             vhd->protocol = prot;
93             vhd->vhost = vhost;
94             break;
95
96         case LWS_CALLBACK_PROTOCOL_DESTROY:
97             if (!vhd) {
98                 break;
99             }
100             break;
101
102         case LWS_CALLBACK_ESTABLISHED:
103             break;
104
105         case LWS_CALLBACK_SERVER_WRITEABLE:
106             n = strlen(line);
107             m = lws_write(wsi, line, n, LWS_WRITE_TEXT);
108             if (m < n) {
109                 printf("ERROR %d writing to di socket\n", n);
110                 return -1;
111             }
112             break;
113
114         case LWS_CALLBACK_RECEIVE:
115             if (strcmp((const char *)in, "reset") == 0) {
116                 strcpy(line, JSON_EMPTY);
117                 lws_callback_on_writable_all_protocol(lws_get_context(wsi),
118                                                       &protocols[PROTOCOL_MERICA_TERMINAL]);
119             } else if (strcmp((const char *)in, "close") == 0) {
120                 printf("dumb_inc: closing as requested\n");
121                 lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY,
122                                  (unsigned char *)"seeya", 5);
123                 return -1;
124             }
125             break;
126
127         default:
128             break;
129     }
130
131     return 0;
132 }
133
134 static void fd_cb(EV_P_ ev_io *w_, int revents)
135 {
136     ev_io_ws *w = (ev_io_ws *)w_;
137
138     char *pos = w->pos++;
139
140     read(w->w.fd, pos, 1);
141
142     if (*pos == '\n') {
143         *pos = 0;
144         w->pos = w->text;
145         lws_callback_on_writable_all_protocol(w->context,
146                                               &protocols[PROTOCOL_MERICA_TERMINAL]);
147     }
148 }
149
150 int mt_server_init(mt_server_t *self, struct ev_loop *loop, int fd)
151 {
152     struct lws_context_creation_info info;
153
154     memset(&info, 0, sizeof(info));
155     info.port = 80;
156     info.mounts = &mount;
157     info.protocols = protocols;
158     info.max_http_header_pool = 1;
159     info.options |= LWS_SERVER_OPTION_LIBEV;
160
161     struct lws_context *context = lws_create_context(&info);
162     if (!context) {
163         fprintf(stderr, "lws_create_context failed\n");
164         return -1;
165     }
166
167     self->context = context;
168
169     ev_io_ws *w = &(self->fd_watcher);
170     w->context = context;
171     w->text = (char *)malloc(512*sizeof(char));
172     if (!w->text) {
173         perror("malloc");
174         return -1;
175     }
176     strcpy(w->text, JSON_EMPTY);
177     w->pos = w->text;
178     protocols[PROTOCOL_MERICA_TERMINAL].user = (void *)w->text;
179     ev_io_init(&(w->w), fd_cb, fd, EV_READ);
180     ev_io_start(loop, (ev_io *)w);
181
182     return lws_ev_initloop(context, loop, 0);
183 }
184
185 void mt_server_deinit(mt_server_t *self)
186 {
187     //free(self->fd_watcher.text);
188     //protocols[PROTOCOL_MERICA_TERMINAL].user = NULL;
189     lws_context_destroy(self->context);
190 }
191
192 #ifdef IS_MAIN
193 int main(int argc, const char **argv)
194 {
195     struct ev_loop *loop = EV_DEFAULT;
196     mt_server_t server;
197
198     set_signal_exit(loop);
199
200     if (mt_server_init(&server, loop, STDIN_FILENO) == -1) {
201         return -1;
202     }
203
204     ev_run(loop, 0);
205
206     mt_server_deinit(&server);
207
208     return 0;
209 }
210 #endif