From 02b3b7acace5d4f14a3c66aa9b58d142ad521afa Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ji=C5=99=C3=AD=20Mat=C4=9Bj=C3=A1k?= Date: Thu, 26 Apr 2018 17:52:38 +0200 Subject: [PATCH] almost ready --- Makefile | 15 ++-- ev_signal_exit.c | 30 +++++++ ev_signal_exit.h | 8 ++ html/index.html | 36 +++++--- mt_rfid.c | 140 +++++++++++++++-------------- mt_rfid.h | 24 +++-- mt_server.c | 223 +++++++++++++++++++---------------------------- mt_server.h | 17 +++- mtps.c | 33 +++++++ 9 files changed, 291 insertions(+), 235 deletions(-) create mode 100644 ev_signal_exit.c create mode 100644 ev_signal_exit.h create mode 100644 mtps.c diff --git a/Makefile b/Makefile index 964d4b2..de47755 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,15 @@ -SOURCE_FILES = mt_rfid.c -OUTPUT_FILE = mt-rfid -LIBRARIES = -lev -luFCoder-armhf - -all: mt-rfid mt-server +all: mt-rfid mt-server mt-ps mt-rfid: $(SOURCE_FILES) - $(CC) $(CFLAGS) -o $(OUTPUT_FILE) $(SOURCE_FILES) $(LIBRARIES) + $(CC) $(CFLAGS) -DIS_MAIN -o mt_rfid mt_rfid.c ev_signal_exit.c -lev -luFCoder-armhf mt-server: mt_server.c - $(CC) $(CFLAGS) -o mt-server mt_server.c $(LIBRARIES) -lwebsockets + $(CC) $(CFLAGS) -DIS_MAIN -o mt-server mt_server.c ev_signal_exit.c -lev -lwebsockets + +mt-ps: mtps.c mt_rfid.c mt_server.c + $(CC) $(CFLAGS) -o mt-ps mtps.c mt_rfid.c mt_server.c ev_signal_exit.c -lev -luFCoder-armhf -lwebsockets .PHONY: clean clean: - rm -f $(OUTPUT_FILE) + rm -f mt-* diff --git a/ev_signal_exit.c b/ev_signal_exit.c new file mode 100644 index 0000000..21c33c5 --- /dev/null +++ b/ev_signal_exit.c @@ -0,0 +1,30 @@ +#include +#include +#include "ev_signal_exit.h" + +static int sigs[] = { SIGINT, SIGKILL, SIGTERM, SIGSEGV, SIGFPE }; +static struct ev_signal signals[5]; + +static void signal_cb(EV_P_ ev_signal *w, int revents) +{ + fprintf(stderr, "signal caught, terminating\n"); + switch (w->signum) { + case SIGTERM: + case SIGINT: + ev_break(loop, EVBREAK_ALL); + break; + default: + signal(SIGABRT, SIG_DFL); + abort(); + break; + } +} + +void set_signal_exit(struct ev_loop *loop) +{ + for (int i = 0; i < 5; i++) { + ev_signal_init(&signals[i], signal_cb, sigs[i]); + ev_signal_start(loop, &signals[i]); + } +} + diff --git a/ev_signal_exit.h b/ev_signal_exit.h new file mode 100644 index 0000000..4c3e5b7 --- /dev/null +++ b/ev_signal_exit.h @@ -0,0 +1,8 @@ +#ifndef EV_SIGNAL_EXIT_H +#define EV_SIGNAL_EXIT_H + +#include + +void set_signal_exit(struct ev_loop *loop); + +#endif diff --git a/html/index.html b/html/index.html index c5e19f3..e5aa108 100644 --- a/html/index.html +++ b/html/index.html @@ -25,41 +25,49 @@ socket.onmessage = function(json) { var msg = JSON.parse(json.data); - update("json", JSON.stringify(msg)) + update("json", "json: " + JSON.stringify(msg)) switch(msg.type) { + case "empty": + update("text",""); + break; case "rfid": - update("text", msg.uid + " " + msg.size); + update("text", + "uid: " + msg.uid + "
" + + "card type: " + msg.card_type + "
" + + "uid size: " + msg.size + " bytes
" + + "sak: " + msg.sak + ); break; } } function sendReset() { - socket.send("reset\n"); + socket.send("reset"); console.log("reset"); } function sendClose() { - socket.send("close\n"); + socket.send("close"); console.log("close"); } + + + + - +

time.is + + + + +

- - - - - - - diff --git a/mt_rfid.c b/mt_rfid.c index 2741277..4f3b07c 100644 --- a/mt_rfid.c +++ b/mt_rfid.c @@ -14,12 +14,12 @@ #include #include -#include #include #include "mt_rfid.h" +#include "ev_signal_exit.h" -int set_nonblock(int fd) +static int set_nonblock(int fd) { int flags = fcntl(fd, F_GETFL, 0); if (flags == -1) { @@ -34,7 +34,7 @@ int set_nonblock(int fd) return 0; } -int set_rts(int fd, int level) +static int set_rts(int fd, int level) { int uart_status; @@ -59,7 +59,7 @@ int set_rts(int fd, int level) return 0; } -void set_baud_rate(int fd, int br) +static void set_baud_rate(int fd, int br) //TODO add some checking { struct termios options; @@ -69,7 +69,7 @@ void set_baud_rate(int fd, int br) tcsetattr(fd, TCSANOW, &options); } -int tty_open(const char *port, int baud_rate) +static int tty_open(const char *port, int baud_rate) { int fd = open(port, O_RDONLY | O_NOCTTY); @@ -89,28 +89,37 @@ int tty_open(const char *port, int baud_rate) return fd; } -typedef struct ev_io_ufr { - ev_io w; - //lws_context *context; - //ufr_session_data *session_data; - char uid_data[24]; - char *uid; - int fd; -} ev_io_ufr; - -static void sigint_cb(EV_P_ ev_signal *w, int revents) -{ - ev_break(EV_A_ EVBREAK_ALL); -} +// really simple JSON helpers +#define JSON_START() dprintf(fd,"{") +#define JSON_NUM(NAME) dprintf(fd,"\"" #NAME "\": %d", NAME) +#define JSON_NEXT() dprintf(fd,",") +#define JSON_STR(NAME) dprintf(fd,"\"" #NAME "\": \"%s\"", NAME) +#define JSON_END() dprintf(fd,"}\n") + +// print complete json +#define JSON_PRINT() do { \ + JSON_START(); \ + JSON_STR(type); \ + JSON_NEXT(); \ + JSON_NUM(card_type); \ + JSON_NEXT(); \ + JSON_NUM(sak); \ + JSON_NEXT(); \ + JSON_NUM(size); \ + JSON_NEXT(); \ + JSON_STR(uid); \ + JSON_END(); \ +} while (0) static void ufr_read(char *uid, int fd) { + static char *type = "rfid"; + UFR_STATUS status; uint8_t card_type; uint8_t sak; //select acknowledge uint8_t uid_bytes[10]; //uid as bytes uint8_t size; - char *type = "rfid"; status = GetDlogicCardType(&card_type); if (status != UFR_OK) { @@ -124,24 +133,11 @@ static void ufr_read(char *uid, int fd) return; } - JSON_START(); - JSON_STR(type); - JSON_NEXT(); - JSON_NUM(card_type); - JSON_NEXT(); - JSON_NUM(sak); - JSON_NEXT(); - JSON_NUM(size); - JSON_NEXT(); - JSON_STR(uid); - JSON_END(); + JSON_PRINT(); #ifdef UFR_BEEP ReaderUISignal(0, 1); // no light, one beep #endif - - /*lws_callback_on_writable_all_protocol(self->context, - &protocols[PROTOCOL_DUMB_INCREMENT]);*/ } static void ufr_cb(EV_P_ ev_io *w_, int revents) @@ -149,44 +145,17 @@ static void ufr_cb(EV_P_ ev_io *w_, int revents) ev_io_ufr *w = (ev_io_ufr *)w_; char uid; read(w->w.fd, &uid, 1); - *(w->uid)++ = uid; + *(w->uid++) = uid; if (uid == ASYNC_SUFFIX) { - //*(w->uid - 1) = 0; + //*(w->uid - 1) = 0; // no need if ASYNC_SUFFIX is 0 w->uid = w->uid_data; ufr_read(w->uid, w->fd); } - - //for one-shot events, one must manually stop the watcher with its corresponding stop function. - //ev_io_stop (EV_A_ w); - - //this causes all nested ev_run's to stop iterating - //ev_break (EV_A_ EVBREAK_ALL); } -ev_io_ufr ufr_watcher; -ev_signal int_watcher, term_watcher; - -int libev_run(int fd) -{ - struct ev_loop *loop = EV_DEFAULT; - - ufr_watcher.uid = ufr_watcher.uid_data; - ufr_watcher.fd = 1; - ev_io_init(&(ufr_watcher.w), ufr_cb, fd, EV_READ); - ev_io_start(loop, (ev_io *)&ufr_watcher); - - ev_signal_init(&int_watcher, sigint_cb, SIGINT); - ev_signal_start(loop, &int_watcher); - ev_signal_init(&term_watcher, sigint_cb, SIGTERM); - ev_signal_start(loop, &term_watcher); - - ev_run(loop, 0); - - return 0; -} - -int ufr_open(unsigned reader_type, char *port_name, unsigned port_interface) +static int ufr_open(unsigned reader_type, char *port_name, + unsigned port_interface) { UFR_STATUS status; @@ -216,31 +185,58 @@ int ufr_open(unsigned reader_type, char *port_name, unsigned port_interface) return 0; } -int main(int argc, char **argv) +int mt_rfid_init(mt_rfid_t *self, struct ev_loop *loop, int fd) { if (ufr_open(READER_TYPE, PORT_NAME, PORT_INTERFACE) == -1) { return -1; } - int fd = tty_open(PORT_NAME, CONCAT(B, ASYNC_BAUD_RATE)); - if (fd < 0) { + int tty = tty_open(PORT_NAME, CONCAT(B, ASYNC_BAUD_RATE)); + if (tty < 0) { return -2; } + self->fd = tty; - libev_run(fd); + ev_io_ufr *w = &(self->w); + w->uid = w->uid_data; + w->fd = fd; + ev_io_init(&(w->w), ufr_cb, tty, EV_READ); + ev_io_start(loop, (ev_io *)w); - if (close(fd) == 0) { - fprintf(stderr, "closed %d\n", fd); + return 0; +} + +void mt_rfid_deinit(mt_rfid_t *self) +{ + if (close(self->fd) == 0) { + fprintf(stderr, "closed %d\n", self->fd); } else { perror("close"); } - UFR_STATUS status; - status = ReaderClose(); + UFR_STATUS status = ReaderClose(); fprintf(stderr, "ReaderClose: %s\n", UFR_Status2String(status)); +} + +#ifdef IS_MAIN +int main(int argc, char **argv) +{ + struct ev_loop *loop = EV_DEFAULT; + mt_rfid_t rfid; + + set_signal_exit(loop); + + if (mt_rfid_init(&rfid, loop, STDOUT_FILENO) != 0) { + return -1; + } + + ev_run(loop, 0); + + mt_rfid_deinit(&rfid); return 0; } +#endif /* other tty options //Enable the receiver and set local mode... diff --git a/mt_rfid.h b/mt_rfid.h index 44ce62a..2c98dd7 100644 --- a/mt_rfid.h +++ b/mt_rfid.h @@ -5,6 +5,8 @@ #ifndef MT_RFID_H #define MT_RFID_H +#include + // reader open parameters, see uFR manual #define READER_TYPE 1 // uFR type (1Mbps) #define PORT_INTERFACE 1 // serial, auto -> ftdi -> FAIL (some shity drivers missing) @@ -14,13 +16,21 @@ #define ASYNC_SUFFIX 0 // keep it zero: + separates uids, + terminates strings #define ASYNC_BAUD_RATE 1000000 // 1Mbps, otherwise UFR_COMMUNICATION_BREAK -#define UFR_BEEP // define this to annoy people +//#define UFR_BEEP // define this to annoy people + +typedef struct ev_io_ufr { + ev_io w; + char uid_data[24]; // this is enough (10 bytes max) + char *uid; + int fd; +} ev_io_ufr; + +typedef struct mt_rfid_t { + ev_io_ufr w; + int fd; +} mt_rfid_t; -// really simple JSON helpers -#define JSON_START() dprintf(fd,"{") -#define JSON_NUM(NAME) dprintf(fd,"\"" #NAME "\": %d", NAME) -#define JSON_NEXT() dprintf(fd,",") -#define JSON_STR(NAME) dprintf(fd,"\"" #NAME "\": \"%s\"", NAME) -#define JSON_END() dprintf(fd,"}\n") +int mt_rfid_init(mt_rfid_t *self, struct ev_loop *loop, int fd); +void mt_rfid_deinit(mt_rfid_t *self); #endif diff --git a/mt_server.c b/mt_server.c index 2df7568..fb5eb1b 100644 --- a/mt_server.c +++ b/mt_server.c @@ -1,27 +1,9 @@ #include #include -#include #include -#include - -char *uids[10] = { - "evelyn", - "sera", - "solas", - "iron bull", - "cassandra", - "varric", - "dorian", - "vivienne", - "blackwall", - "cole" -}; -#define JSON_STRING "{" \ - "\"type\": \"rfid\"," \ - "\"uid\": \"%s\"," \ - "\"size\": %d" \ - "}\n" +#include "mt_server.h" +#include "ev_signal_exit.h" static const struct lws_http_mount mount = { /* .mount_next */ NULL, /* linked-list "next" */ @@ -57,40 +39,59 @@ typedef struct per_session_data__dumb_increment { int number; } per_session_data__dumb_increment; -typedef struct user_data { - //ev_ufr_io *ufr; -} user_data; +#define JSON_EMPTY "{\"type\":\"empty\"}" + +enum protocols { + PROTOCOL_HTTP = 0, // always first + PROTOCOL_MERICA_TERMINAL +}; - static char line[512]; +static int callback_merica_terminal(struct lws *wsi, + enum lws_callback_reasons reason, + void *user, void *in, size_t len); + +/* list of supported protocols and callbacks */ + +static struct lws_protocols protocols[] = { + /* first protocol must always be HTTP handler */ + {"http", lws_callback_http_dummy, 0, 0}, + { + "dumb-increment-protocol", + callback_merica_terminal, + sizeof(struct per_session_data__dumb_increment), + 128, /* rx buf size must be >= permessage-deflate rx size + * dumb-increment only sends very small packets, so we set + * this accordingly. If your protocol will send bigger + * things, adjust this to match */ + }, + {NULL, NULL, 0, 0} /* terminator */ +}; -static int callback_dumb_increment(struct lws *wsi, - enum lws_callback_reasons reason, - void *user, void *in, size_t len) +static int callback_merica_terminal(struct lws *wsi, + enum lws_callback_reasons reason, + void *user, void *in, size_t len) { + struct lws_vhost *vhost = lws_get_vhost(wsi); + const struct lws_protocols *prot = lws_get_protocol(wsi); per_session_data__dumb_increment *pss = (per_session_data__dumb_increment *)user; per_vhost_data__dumb_increment *vhd = (per_vhost_data__dumb_increment *) - lws_protocol_vh_priv_get(lws_get_vhost(wsi), lws_get_protocol(wsi)); - - struct lws_context *context = lws_get_context(wsi); - user_data *data = (user_data *)lws_context_user(context); + lws_protocol_vh_priv_get(vhost, prot); - - unsigned char buf[LWS_PRE + 512]; - unsigned char *p = &buf[LWS_PRE]; int n, m; + char *line = (char *)prot->user; + switch (reason) { case LWS_CALLBACK_PROTOCOL_INIT: vhd = lws_protocol_vh_priv_zalloc( - lws_get_vhost(wsi), - lws_get_protocol(wsi), + vhost, prot, sizeof(struct per_vhost_data__dumb_increment) ); vhd->context = lws_get_context(wsi); - vhd->protocol = lws_get_protocol(wsi); - vhd->vhost = lws_get_vhost(wsi); + vhd->protocol = prot; + vhd->vhost = vhost; break; case LWS_CALLBACK_PROTOCOL_DESTROY: @@ -100,13 +101,10 @@ static int callback_dumb_increment(struct lws *wsi, break; case LWS_CALLBACK_ESTABLISHED: - pss->number = 0; break; case LWS_CALLBACK_SERVER_WRITEABLE: - n = sprintf((char *)p, JSON_STRING, uids[pss->number % 10], pss->number); - pss->number++; - n = strlen(line); + n = strlen(line); m = lws_write(wsi, line, n, LWS_WRITE_TEXT); if (m < n) { printf("ERROR %d writing to di socket\n", n); @@ -115,13 +113,11 @@ static int callback_dumb_increment(struct lws *wsi, break; case LWS_CALLBACK_RECEIVE: - if (len < 6) { - break; - } - if (strcmp((const char *)in, "reset\n") == 0) { - pss->number = 0; - } - if (strcmp((const char *)in, "close\n") == 0) { + if (strcmp((const char *)in, "reset") == 0) { + strcpy(line, JSON_EMPTY); + lws_callback_on_writable_all_protocol(lws_get_context(wsi), + &protocols[PROTOCOL_MERICA_TERMINAL]); + } else if (strcmp((const char *)in, "close") == 0) { printf("dumb_inc: closing as requested\n"); lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY, (unsigned char *)"seeya", 5); @@ -136,129 +132,92 @@ static int callback_dumb_increment(struct lws *wsi, return 0; } -enum demo_protocols { - /* always first */ - PROTOCOL_HTTP = 0, - - PROTOCOL_DUMB_INCREMENT, - PROTOCOL_LWS_MIRROR, - PROTOCOL_LWS_STATUS, - - /* always last */ - DEMO_PROTOCOL_COUNT -}; +/*static void ev_timeout_cb(EV_P_ ev_timer *w, int revents) +{ + lws_callback_on_writable_all_protocol(context, + &protocols[PROTOCOL_MERICA_TERMINAL]); +}*/ -/* list of supported protocols and callbacks */ -static struct lws_protocols protocols[] = { - /* first protocol must always be HTTP handler */ - {"http", lws_callback_http_dummy, 0, 0}, - { - "dumb-increment-protocol", - callback_dumb_increment, - sizeof(struct per_session_data__dumb_increment), - 128, /* rx buf size must be >= permessage-deflate rx size - * dumb-increment only sends very small packets, so we set - * this accordingly. If your protocol will send bigger - * things, adjust this to match */ - }, - {NULL, NULL, 0, 0} /* terminator */ -}; +static void fd_cb(EV_P_ ev_io *w_, int revents) +{ + ev_io_ws *w = (ev_io_ws *)w_; -struct lws_context *context; + char *pos = w->pos++; -static void ev_timeout_cb(EV_P_ ev_timer *w, int revents) -{ - lws_callback_on_writable_all_protocol(context, - &protocols[PROTOCOL_DUMB_INCREMENT]); -} + read(w->w.fd, pos, 1); -static void signal_cb(EV_P_ ev_signal *w, int revents) -{ - fprintf(stderr, "signal caught, terminating\n"); - switch (w->signum) { - case SIGTERM: - case SIGINT: - ev_break(loop, EVBREAK_ALL); - break; - default: - signal(SIGABRT, SIG_DFL); - abort(); - break; + if (*pos == '\n') { + *pos = 0; + w->pos = w->text; + lws_callback_on_writable_all_protocol(w->context, + &protocols[PROTOCOL_MERICA_TERMINAL]); } -} - +} -int server_init(void *user) +int mt_server_init(mt_server_t *self, struct ev_loop *loop, int fd) { struct lws_context_creation_info info; - protocols[PROTOCOL_DUMB_INCREMENT].user = (void *)line; - - memset(&info, 0, sizeof info); + memset(&info, 0, sizeof(info)); info.port = 80; info.mounts = &mount; info.protocols = protocols; info.max_http_header_pool = 1; info.options |= LWS_SERVER_OPTION_LIBEV; - info.user = user; - context = lws_create_context(&info); + struct lws_context *context = lws_create_context(&info); if (!context) { fprintf(stderr, "lws_create_context failed\n"); return -1; } - return 0; -} + self->context = context; + ev_io_ws *w = &(self->fd_watcher); + w->context = context; + w->text = (char *)malloc(512*sizeof(char)); + if (!w->text) { + perror("malloc"); + return -1; + } + strcpy(w->text, JSON_EMPTY); + w->pos = w->text; + protocols[PROTOCOL_MERICA_TERMINAL].user = (void *)w->text; + ev_io_init(&(w->w), fd_cb, fd, EV_READ); + ev_io_start(loop, (ev_io *)w); + return lws_ev_initloop(context, loop, 0); +} -static void stdin_cb(EV_P_ ev_io *w, int revents) +void mt_server_deinit(mt_server_t *self) { - static int pos = 0; - - read(w->fd, &line[pos++], 1); - - if (line[pos-1] == '\n') { - line[pos] = 0; - pos = 0; -// puts(line); - lws_callback_on_writable_all_protocol(context, - &protocols[PROTOCOL_DUMB_INCREMENT]); - } - + //free(self->fd_watcher.text); + //protocols[PROTOCOL_MERICA_TERMINAL].user = NULL; + lws_context_destroy(self->context); } +#ifdef IS_MAIN int main(int argc, const char **argv) { - int sigs[] = { SIGINT, SIGKILL, SIGTERM, SIGSEGV, SIGFPE }; - struct ev_signal signals[ARRAY_SIZE(sigs)]; - ev_io stdin_watcher; struct ev_loop *loop = ev_default_loop(0); - ev_timer timeout_watcher; + mt_server_t server; - for (int n = 0; n < ARRAY_SIZE(sigs); n++) { - ev_init(&signals[n], signal_cb); - ev_signal_set(&signals[n], sigs[n]); - ev_signal_start(loop, &signals[n]); - } + set_signal_exit(loop); - if (server_init(NULL) == -1) { + if (mt_server_init(&server, loop, STDIN_FILENO) == -1) { return -1; } - lws_ev_initloop(context, loop, 0); - - ev_io_init(&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); - ev_io_start(loop, &stdin_watcher); - ev_timer_init(&timeout_watcher, ev_timeout_cb, 1, 1); + //ev_timer timeout_watcher; + //ev_timer_init(&timeout_watcher, ev_timeout_cb, 1, 1); //ev_timer_start(loop, &timeout_watcher); ev_run(loop, 0); - lws_context_destroy(context); + mt_server_deinit(&server); return 0; } +#endif diff --git a/mt_server.h b/mt_server.h index a2cab9d..80261ea 100644 --- a/mt_server.h +++ b/mt_server.h @@ -2,8 +2,21 @@ #define MT_SERVER_H #include +#include -int mt_server_init(struct ev_loop *loop, int fd); -void mt_server_deinit(); +typedef struct ev_io_ws { + ev_io w; + struct lws_context *context; + char *text; + char *pos; +} ev_io_ws; + +typedef struct mt_server_t { + struct lws_context *context; + ev_io_ws fd_watcher; +} mt_server_t; + +int mt_server_init(mt_server_t *self, struct ev_loop *loop, int fd); +void mt_server_deinit(mt_server_t *self); #endif diff --git a/mtps.c b/mtps.c new file mode 100644 index 0000000..21f3686 --- /dev/null +++ b/mtps.c @@ -0,0 +1,33 @@ +#include "mt_rfid.h" +#include "mt_server.h" +#include "ev_signal_exit.h" + +int main(int argc, char **argv) +{ + struct ev_loop *loop = EV_DEFAULT; + int pipefd[2]; // read <- write + mt_rfid_t rfid; + mt_server_t server; + + if (pipe(pipefd) == -1) { + perror("pipe"); + return -1; + } + + set_signal_exit(loop); + + if (mt_rfid_init(&rfid, loop, pipefd[1]) != 0) { + return -1; + } + + if (mt_server_init(&server, loop, pipefd[0]) != 0) { + return -2; + } + + ev_run(loop, 0); + + mt_server_deinit(&server); + mt_rfid_deinit(&rfid); + + return 0; +} -- 2.39.2