-all: mt-rfid mt-server mt-ps
+OUTPUT_DIR = build
-mt-rfid: $(SOURCE_FILES)
- $(CC) $(CFLAGS) -DIS_MAIN -o mt_rfid mt_rfid.c ev_signal_exit.c -lev -luFCoder-armhf
+all: mtrfid mtserver mtps
-mt-server: mt_server.c
- $(CC) $(CFLAGS) -DIS_MAIN -o mt-server mt_server.c ev_signal_exit.c -lev -lwebsockets
+mtrfid: mt_rfid.c
+ mkdir -p $(OUTPUT_DIR)
+ $(CC) $(CFLAGS) -DIS_MAIN -o $(OUTPUT_DIR)/mtrfid mt_rfid.c signal_exit.c -lev -luFCoder-armhf
-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
+mtserver: mt_server.c
+ mkdir -p $(OUTPUT_DIR)
+ $(CC) $(CFLAGS) -DIS_MAIN -o $(OUTPUT_DIR)/mtserver mt_server.c signal_exit.c -lev -lwebsockets
+
+mtps: mt_ps.c mt_rfid.c mt_server.c
+ mkdir -p $(OUTPUT_DIR)
+ $(CC) $(CFLAGS) -o $(OUTPUT_DIR)/mtps mt_ps.c mt_rfid.c mt_server.c signal_exit.c -lev -luFCoder-armhf -lwebsockets
.PHONY: clean
clean:
- rm -f mt-*
+ rm -rf $(OUTPUT_DIR)
<script>
var socket = new WebSocket(
"ws://" + document.domain + ':' + location.port,
- "dumb-increment-protocol"
+ "merica-terminal-protocol"
);
function update(id, msg) {
+// merica terminal peripheral server
#include "mt_rfid.h"
#include "mt_server.h"
-#include "ev_signal_exit.h"
+#include "signal_exit.h"
int main(int argc, char **argv)
{
-/**
- * mt_rfid.c
- */
-
-// shit to avoid constant repetition
-#define CONCAT_AGAIN(A,B) A ## B
-#define CONCAT(A,B) CONCAT_AGAIN(A,B)
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <uFCoder.h>
#include "mt_rfid.h"
-#include "ev_signal_exit.h"
+#include "signal_exit.h"
+
+// shit to avoid constant repetition
+#define CONCAT_AGAIN(A,B) A ## B
+#define CONCAT(A,B) CONCAT_AGAIN(A,B)
static int set_nonblock(int fd)
{
tcsetattr(fd, TCSANOW, &options);
}
-static int tty_open(const char *port, int baud_rate)
+static int tty_open(const char *port, int br)
{
int fd = open(port, O_RDONLY | O_NOCTTY);
}
set_nonblock(fd);
- set_rts(fd, 0);
- set_baud_rate(fd, baud_rate);
- usleep(1200000); //value by d-logic
+ set_rts(fd, 0); //disable
+ set_baud_rate(fd, br);
+ usleep(1200000); //value by d-logic
tcflush(fd, TCIFLUSH);
return fd;
// really simple JSON helpers
#define JSON_START() dprintf(fd,"{")
-#define JSON_NUM(NAME) dprintf(fd,"\"" #NAME "\": %d", NAME)
+#define JSON_NUM(NAME) dprintf(fd,"\"" #NAME "\":%d", NAME) //see the int?
#define JSON_NEXT() dprintf(fd,",")
-#define JSON_STR(NAME) dprintf(fd,"\"" #NAME "\": \"%s\"", NAME)
+#define JSON_STR(NAME) dprintf(fd,"\"" #NAME "\":\"%s\"", NAME)
#define JSON_END() dprintf(fd,"}\n")
// print complete json
#endif
}
+#define UFR_ASYNC_SUFFIX 0 // keep it zero: separates uids, terminates strings
+
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;
- if (uid == ASYNC_SUFFIX) {
- //*(w->uid - 1) = 0; // no need if ASYNC_SUFFIX is 0
+ if (uid == UFR_ASYNC_SUFFIX) {
+ //*(w->uid - 1) = 0; // no need if UFR_ASYNC_SUFFIX is 0
w->uid = w->uid_data;
ufr_read(w->uid, w->fd);
}
fprintf(stderr, "%s\n", GetReaderDescription());
status = SetAsyncCardIdSendConfig(
- 1, //enable send
- 0, //disable prefix
- 0, //prefix
- ASYNC_SUFFIX, //suffix
- 0, //disable send removed
- ASYNC_BAUD_RATE
+ 1, //enable send
+ 0, //disable prefix
+ 0, //prefix
+ UFR_ASYNC_SUFFIX, //suffix
+ 0, //disable send removed
+ UFR_ASYNC_BAUD_RATE
);
fprintf(stderr, "SetAsyncCardIdSendConfig: %s\n", UFR_Status2String(status));
if (status != UFR_OK) {
int mt_rfid_init(mt_rfid_t *self, struct ev_loop *loop, int fd)
{
- if (ufr_open(READER_TYPE, PORT_NAME, PORT_INTERFACE) == -1) {
+ if (ufr_open(UFR_READER_TYPE, UFR_PORT_NAME, UFR_PORT_INTERFACE) == -1) {
return -1;
}
- int tty = tty_open(PORT_NAME, CONCAT(B, ASYNC_BAUD_RATE));
+ int tty = tty_open(UFR_PORT_NAME, CONCAT(B, UFR_ASYNC_BAUD_RATE));
if (tty < 0) {
return -2;
}
return 0;
}
#endif
-
-/* other tty options
- //Enable the receiver and set local mode...
- options.c_cflag |= (CLOCAL | CREAD);
-
- options.c_cflag &= ~PARENB;
- options.c_cflag &= ~CSTOPB;
- options.c_cflag &= ~CSIZE;
- options.c_cflag |= CS8;
- options.c_cflag &= ~CRTSCTS;
- options.c_lflag |= (ICANON | ECHO | ECHOE);
- //Disable XON/XOFF both i/p and o/p
- options.c_iflag &= ~(IXON | IXOFF | IXANY);
- //Non Cannon mode
- options.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
-
- options.c_oflag |= OPOST;
-*/
-
-/**
- * mt_rfid.h
- */
-
#ifndef MT_RFID_H
#define MT_RFID_H
#include <ev.h>
// 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)
-#define PORT_NAME "/dev/ttyUSB0"
-
-// async uid sending parameters
-#define ASYNC_SUFFIX 0 // keep it zero: + separates uids, + terminates strings
-#define ASYNC_BAUD_RATE 1000000 // 1Mbps, otherwise UFR_COMMUNICATION_BREAK
+#define UFR_READER_TYPE 1 // uFR type (1Mbps)
+#define UFR_PORT_INTERFACE 1 // serial; auto->ftdi->FAIL
+#define UFR_PORT_NAME "/dev/ttyUSB0" // reader device
+#define UFR_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 w; // fd watcher
+ char uid_data[24]; // store uid here (uid is 10 bytes max)
+ char *uid; // current position in uid_data
+ int fd; // PORT_NAME file descriptor
} ev_io_ufr;
typedef struct mt_rfid_t {
- ev_io_ufr w;
- int fd;
+ ev_io_ufr w; // reader watcher
+ int fd; // print JSON output here
} mt_rfid_t;
+// connect to the reader, add self to loop and make it write to fd
int mt_rfid_init(mt_rfid_t *self, struct ev_loop *loop, int fd);
+
+// disconnect from reader
void mt_rfid_deinit(mt_rfid_t *self);
#endif
#include <string.h>
#include "mt_server.h"
-#include "ev_signal_exit.h"
-
-#define JSON_EMPTY "{\"type\":\"empty\"}"
+#include "signal_exit.h"
static const struct lws_http_mount mount = {
/* .mount_next */ NULL, /* linked-list "next" */
- /* .mountpoint */ "/", /* mountpoint URL */
- /* .origin */ "/usr/share/mt-server", /* serve from dir */
- /* .def */ "index.html", /* default filename */
+ /* .mountpoint */ HTTP_MOUNTPOINT,
+ /* .origin */ HTTP_ORIGIN, /* serve from dir */
+ /* .def */ HTTP_DEFAULT, /* default filename */
/* .protocol */ NULL,
/* .cgienv */ NULL,
/* .extra_mimetypes */ NULL,
/* .basic_auth_login_file */ NULL,
};
-typedef struct per_vhost_data__dumb_increment {
+typedef struct per_vhost_data__merica_terminal {
struct lws_context *context;
struct lws_vhost *vhost;
const struct lws_protocols *protocol;
-} per_vhost_data__dumb_increment;
+} per_vhost_data__merica_terminal;
-typedef struct per_session_data__dumb_increment {
- uint8_t card_type;
- uint8_t sak;
- uint8_t uid_size;
- char *uid;
+/*
+typedef struct per_session_data__merica_terminal {
int number;
-} per_session_data__dumb_increment;
+} per_session_data__merica_terminal;
+*/
enum protocols {
PROTOCOL_HTTP = 0, // always first
// list of supported protocols and callbacks
static struct lws_protocols protocols[] = {
- /* first protocol must always be HTTP handler */
+ // first protocol must always be HTTP handler
{"http", lws_callback_http_dummy, 0, 0},
{
- "dumb-increment-protocol",
+ "merica-terminal-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 */
+ 0, //sizeof(struct per_session_data__merica_terminal),
+ MT_PROTOCOL_RX_BUFFER_SIZE
},
- {NULL, NULL, 0, 0} /* terminator */
+ {NULL, NULL, 0, 0} // terminator
};
static int callback_merica_terminal(struct lws *wsi,
{
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 *)
+ /*
+ per_session_data__merica_terminal *pss =
+ (per_session_data__merica_terminal *)user;
+ */
+ per_vhost_data__merica_terminal *vhd =
+ (per_vhost_data__merica_terminal *)
lws_protocol_vh_priv_get(vhost, prot);
int n, m;
case LWS_CALLBACK_PROTOCOL_INIT:
vhd = lws_protocol_vh_priv_zalloc(
vhost, prot,
- sizeof(struct per_vhost_data__dumb_increment)
+ sizeof(struct per_vhost_data__merica_terminal)
);
vhd->context = lws_get_context(wsi);
vhd->protocol = prot;
n = strlen(line);
m = lws_write(wsi, line, n, LWS_WRITE_TEXT);
if (m < n) {
- printf("ERROR %d writing to di socket\n", n);
+ fprintf(stderr, "ERROR %d writing to di socket\n", n);
return -1;
}
break;
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");
+ fprintf(stderr, "closing as WebSocket\n");
lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY,
(unsigned char *)"seeya", 5);
return -1;
read(w->w.fd, pos, 1);
- if (*pos == '\n') {
+ if (*pos == '\n' || (w->pos - w->text) == INPUT_LINE_LENGTH) {
*pos = 0;
w->pos = w->text;
lws_callback_on_writable_all_protocol(w->context,
struct lws_context_creation_info info;
memset(&info, 0, sizeof(info));
- info.port = 80;
+ info.port = HTTP_PORT;
info.mounts = &mount;
info.protocols = protocols;
info.max_http_header_pool = 1;
ev_io_ws *w = &(self->fd_watcher);
w->context = context;
- w->text = (char *)malloc(512*sizeof(char));
+ w->text = (char *)malloc(INPUT_LINE_LENGTH*sizeof(char));
if (!w->text) {
perror("malloc");
return -1;
return lws_ev_initloop(context, loop, 0);
}
-void mt_server_deinit(mt_server_t *self)
+void mt_server_deinit(mt_server_t *self) //TODO wtf
{
//free(self->fd_watcher.text);
//protocols[PROTOCOL_MERICA_TERMINAL].user = NULL;
#include <ev.h>
#include <libwebsockets.h>
+// set these two according to your data
+// rx buf size must be >= permessage-deflate rx size
+#define MT_PROTOCOL_RX_BUFFER_SIZE 128
+#define INPUT_LINE_LENGTH 512
+
+#define HTTP_PORT 80 // listen here
+#define HTTP_MOUNTPOINT "/" // mountpoint URL
+#define HTTP_ORIGIN "/usr/share/mt-server" // where the html files are
+#define HTTP_DEFAULT "index.html" // default filename
+
+#define JSON_EMPTY "{\"type\":\"empty\"}" // default message
+
typedef struct ev_io_ws {
- ev_io w;
+ ev_io w; // input watcher
struct lws_context *context;
- char *text;
- char *pos;
+ char *text; // input buffer pointer
+ char *pos; // input buffer current position pointer
} ev_io_ws;
typedef struct mt_server_t {
struct lws_context *context;
- ev_io_ws fd_watcher;
+ ev_io_ws fd_watcher; // input watcher
} mt_server_t;
+// init self, add it to loop and make it read data from fd
int mt_server_init(mt_server_t *self, struct ev_loop *loop, int fd);
+
+// gett drunc an kil sellf
void mt_server_deinit(mt_server_t *self);
#endif
#include <stdlib.h>
#include <stdio.h>
-#include "ev_signal_exit.h"
+#include "signal_exit.h"
-static int sigs[] = { SIGINT, SIGKILL, SIGTERM, SIGSEGV, SIGFPE };
+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)
#include <ev.h>
+// make loop break on signal
void set_signal_exit(struct ev_loop *loop);
#endif