X-Git-Url: https://rtime.felk.cvut.cz/gitweb/coffee/mt-apps.git/blobdiff_plain/97af76e74776b6e4de7d58983a622950bf9ea62b..f75a57f37770949aa1643a20fe47a56b85393ba3:/mt_rfid.c diff --git a/mt_rfid.c b/mt_rfid.c index 328350c..76a94c5 100644 --- a/mt_rfid.c +++ b/mt_rfid.c @@ -1,132 +1,215 @@ -/* - ============================================================================ - Name : main.c - Author : Digital Logic - Version : 1.0 - Copyright : - Description : Very simple test of uFR library - ============================================================================ - */ - #include #include #include -#include -#include +#include +#include +#include + +#include #include "mt_rfid.h" -#include "uFCoder.h" +#include "signal_exit.h" +#include "json_helpers.h" -#define READER_TYPE 1 //uFR type (1Mbps) -#ifndef PORT_NAME -#define PORT_NAME "/dev/ttyUSB0" //"" for auto -#endif -#define PORT_INTERFACE 1 //Serial +// 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) +{ + int flags = fcntl(fd, F_GETFL, 0); + if (flags == -1) { + perror("fcntl (get)"); + return -1; + } + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { + perror("fcntl (set)"); + return -1; + } + fprintf(stderr, "set %d non-blocking\n", fd); + return 0; +} + +static int set_rts(int fd, int level) +{ + int uart_status; + + if (ioctl(fd, TIOCMGET, &uart_status) == -1) { + perror("ioctl (TIOCMGET)"); + return -1; + } + + if (level) { + uart_status |= TIOCM_RTS; + } else { + uart_status &= ~TIOCM_RTS; + } + + if (ioctl(fd, TIOCMSET, &uart_status) == -1) { + perror("TIOCMSET"); + return -1; + } -// really simple JSON helpers -#define JSON_NUM(NAME) printf("\"" #NAME "\": %d", NAME) -#define JSON_STR(NAME) printf("\"" #NAME "\": \"%s\"", NAME) -#define JSON_START() printf("{\n") -#define JSON_NEXT() printf(",\n") -#define JSON_END() printf("\n}\n") + fprintf(stderr, "set %d rts %d\n", fd, level); -static mt_rfid_t ufr = {READER_TYPE, PORT_NAME, PORT_INTERFACE, 0, 1}; + return 0; +} -static void signal_exit(int sig) +static void set_baud_rate(int fd, int br) //TODO add some checking { - ufr.run = 0; - fprintf(stderr, "signal %d, terminating\n", sig); + struct termios options; + + tcgetattr(fd, &options); + cfsetispeed(&options, br); + cfsetospeed(&options, br); + tcsetattr(fd, TCSANOW, &options); } -void *mt_rfid_run(void *ptr) +static int tty_open(const char *port, int br) { - mt_rfid_t *self = (mt_rfid_t *)ptr; - UFR_STATUS status; + int fd = open(port, O_RDONLY | O_NOCTTY); + if (fd < 0) { + perror("open"); + return fd; + } else { + fprintf(stderr, "opened %s as %d\n", port, fd); + } + + set_nonblock(fd); + set_rts(fd, 0); //disable + set_baud_rate(fd, br); + usleep(1200000); //value by d-logic + tcflush(fd, TCIFLUSH); + + return fd; +} + +static void ufr_read(char *uid, int fd) +{ + UFR_STATUS status; uint8_t card_type; - uint8_t sak; //select acknowledge - uint8_t uid_num[10]; //uid as bytes - uint8_t uid_size; - char uid[24]; //uid as a string + uint8_t sak; //select acknowledge + uint8_t uid_bytes[10]; //uid as bytes + uint8_t size; - fprintf(stderr, "uFCoder library version: %s\n", GetDllVersionStr()); + status = GetDlogicCardType(&card_type); + if (status != UFR_OK) { + fprintf(stderr, "GetDlogicCardType: %s\n", UFR_Status2String(status)); + return; + } - status = ReaderOpenEx(self->reader_type, self->port_name, self->port_interface, 0); + status = GetCardIdEx(&sak, uid_bytes, &size); + if (status != UFR_OK) { + fprintf(stderr, "GetCardIdEx: %s\n", UFR_Status2String(status)); + return; + } + + rfid_json_print(fd, card_type, sak, uid, size); + +#ifdef UFR_BEEP + ReaderUISignal(0, 1); // no light, one beep +#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 == 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); + } +} + +static int ufr_open(unsigned reader_type, char *port_name, + unsigned port_interface) +{ + UFR_STATUS status; + + fprintf(stderr, "uFCoder version: %s\n", GetDllVersionStr()); + + status = ReaderOpenEx(reader_type, port_name, port_interface, 0); if (status != UFR_OK) { fprintf(stderr, "ReaderOpenEx: %s\n", UFR_Status2String(status)); - return NULL; + return -1; } - fputs(GetReaderDescription(), stderr); - - while (self->run) { - status = GetDlogicCardType(&card_type); - if (status != UFR_OK) { - if (status != UFR_NO_CARD) { - fprintf(stderr, "GetDlogicCardType: %s\n", UFR_Status2String(status)); - } - usleep(10000); - continue; - } - - status = GetCardIdEx(&sak, uid_num, &uid_size); - if (status != UFR_OK) { - if (status != UFR_NO_CARD) { - fprintf(stderr, "GetCardIdEx: %s\n", UFR_Status2String(status)); - } - usleep(10000); - continue; - } - - for (uint8_t i = 0; i < uid_size; i++) { - sprintf(&uid[2*i], "%02x", uid_num[i]); - } - - JSON_START(); - JSON_NUM(card_type); JSON_NEXT(); - JSON_NUM(sak); JSON_NEXT(); - JSON_NUM(uid_size); JSON_NEXT(); - JSON_STR(uid); JSON_END(); - - if (self->beep) { - ReaderUISignal(0, 1); - } - - usleep(500000); + fprintf(stderr, "%s\n", GetReaderDescription()); + + status = SetAsyncCardIdSendConfig( + 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) { + return -1; } - status = ReaderClose(); - fprintf(stderr, "ReaderClose: %s\n", UFR_Status2String(status)); + return 0; +} + +int mt_rfid_init(mt_rfid_t *self, struct ev_loop *loop, int fd) +{ + if (ufr_open(UFR_READER_TYPE, UFR_PORT_NAME, UFR_PORT_INTERFACE) == -1) { + return -1; + } + + int tty = tty_open(UFR_PORT_NAME, CONCAT(B, UFR_ASYNC_BAUD_RATE)); + if (tty < 0) { + return -2; + } + self->fd = tty; + + 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); + + 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"); + } - return NULL; + UFR_STATUS status = ReaderClose(); + fprintf(stderr, "ReaderClose: %s\n", UFR_Status2String(status)); } +#ifndef NO_MAIN int main(int argc, char **argv) { - pthread_t t; - char c; - - while ((c = getopt(argc, argv, "p:bh")) != -1) { - switch (c) { - case 'p': - ufr.port_name = optarg; - break; - case 'b': - ufr.beep = 1; - break; - } - } + struct ev_loop *loop = EV_DEFAULT; + mt_rfid_t rfid; - // avoid sigaction for windows compatibility - signal(SIGINT, signal_exit); - signal(SIGTERM, signal_exit); + set_signal_exit(loop); - if (pthread_create(&t, NULL, mt_rfid_run, (void *)&ufr)) { - perror("pthread_create"); + if (mt_rfid_init(&rfid, loop, STDOUT_FILENO) != 0) { return -1; } - pthread_join(t, NULL); + ev_run(loop, 0); + + mt_rfid_deinit(&rfid); + ev_loop_destroy(loop); return 0; } +#endif