]> rtime.felk.cvut.cz Git - coffee/mt-apps.git/commitdiff
async uid + libev
authorJiří Matěják <jiri.matejak@fel.cvut.cz>
Tue, 24 Apr 2018 15:24:25 +0000 (17:24 +0200)
committerJiří Matěják <jiri.matejak@fel.cvut.cz>
Tue, 24 Apr 2018 15:24:25 +0000 (17:24 +0200)
mt_rfid.c
mt_rfid.h

index 3d4ab3b84f80023e38ffb3b612011ed3f87665d2..a16dffb267376c81b3968ee55c62eed95ece8c4c 100644 (file)
--- a/mt_rfid.c
+++ b/mt_rfid.c
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <pthread.h>
-#include <signal.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include <ev.h>
+#include <uFCoder.h>
 
 #include "mt_rfid.h"
-#include "uFCoder.h"
 
-// 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")
+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 non-blocking\n");
+    return 0;
+}
+
+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;
+       }
+
+    fprintf(stderr, "set rts %d\n", level);
+
+    return 0;
+}
+
+void set_baud_rate(int fd, int br) {
+       struct termios options;
+
+       tcgetattr(fd, &options);
+       cfsetispeed(&options, br);
+       cfsetospeed(&options, br);
+       tcsetattr(fd, TCSANOW, &options);
+}
+
+int tty_open(const char *port, int baud_rate) {
+
+       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);
+       set_baud_rate(fd, baud_rate);
+       usleep(1200000); //value by d-logic
+       tcflush(fd, TCIFLUSH);
+
+       return fd;
+}
 
-static mt_rfid_t ufr = {READER_TYPE, PORT_NAME, PORT_INTERFACE, 0, 1};
+typedef struct ev_io_ufr {
+    ev_io w;
+    char uid_data[24];
+    char *uid;
+} ev_io_ufr;
 
-static void signal_exit(int sig)
+static void sigint_cb(EV_P_ ev_signal *w, int revents)
 {
-    ufr.run = 0;
-    fprintf(stderr, "signal %d, terminating\n", sig);
+    ev_break (EV_A_  EVBREAK_ALL);
 }
 
-void *mt_rfid_run(void *ptr)
+static void ufr_read(char *uid)
 {
-    mt_rfid_t *self = (mt_rfid_t *)ptr;
     UFR_STATUS status;
-
     uint8_t card_type;
     uint8_t sak;         //select acknowledge
-    uint8_t uid_num[10]; //uid as bytes
+    uint8_t uid_bytes[10]; //uid as bytes
     uint8_t uid_size;
-    char uid[24];        //uid as a string
 
-    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, &uid_size);
     if (status != UFR_OK) {
-        fprintf(stderr, "ReaderOpenEx: %s\n", UFR_Status2String(status));
-        return NULL;
+        fprintf(stderr, "GetCardIdEx: %s\n", UFR_Status2String(status));
+        return;
     }
 
-    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);
+    JSON_START();
+    JSON_NUM(card_type); JSON_NEXT();
+    JSON_NUM(sak);       JSON_NEXT();
+    JSON_NUM(uid_size);  JSON_NEXT();
+    JSON_STR(uid);    JSON_END();
+
+    ReaderUISignal(0, 1);
+}
+
+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;
+        w->uid = w->uid_data;
+        ufr_read(w->uid);
     }
 
-    status = ReaderClose();
-    fprintf(stderr, "ReaderClose: %s\n", UFR_Status2String(status));
+    //for one-shot events, one must manually stop the watcher with its corresponding stop function.
+    //ev_io_stop (EV_A_ w);
 
-    return NULL;
+    //this causes all nested ev_run's to stop iterating
+    //ev_break (EV_A_ EVBREAK_ALL);
 }
 
-int main(int argc, char **argv)
+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;
+    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)
 {
-    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;
-        }
+    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 -1;
+    }
+
+    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
+    );
+    fprintf(stderr, "SetAsyncCardIdSendConfig: %s\n", UFR_Status2String(status));
+    if (status != UFR_OK) {
+        return -1;
     }
 
-    // avoid sigaction for windows compatibility
-    signal(SIGINT, signal_exit);
-    signal(SIGTERM, signal_exit);
+    return 0;
+}
 
-    if (pthread_create(&t, NULL, mt_rfid_run, (void *)&ufr)) {
-        perror("pthread_create");
+int main(int argc, char **argv)
+{
+    if (ufr_open(READER_TYPE, PORT_NAME, PORT_INTERFACE) == -1) {
         return -1;
     }
 
-    pthread_join(t, NULL);
+    int fd = tty_open(PORT_NAME, BASYNC_BAUD_RATE);
+    if (fd < 0) {
+        return -2;
+    }
+
+       libev_run(fd);
+
+    close(fd);
+    fprintf(stderr, "closed %d\n", fd);
+
+    UFR_STATUS status;
+    status = ReaderClose();
+    fprintf(stderr, "ReaderClose: %s\n", UFR_Status2String(status));
 
     return 0;
 }
+
+/* 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;
+*/
+
index 60c4515ba22fb1555366ed874f0077d760d0241e..5d9596099d5ee6dccec86d2900ee78e771754156 100644 (file)
--- a/mt_rfid.h
+++ b/mt_rfid.h
@@ -20,26 +20,17 @@ typedef struct {
 // macros for convenience
 #define READER_TYPE    1 // uFR type (1Mbps)
 #define PORT_INTERFACE 1 // serial
-#ifndef PORT_NAME
 #define PORT_NAME "/dev/ttyUSB0"
-#endif
-
-// poll the uFR reader and print JSON formatted card info to stdout.
-// run it directly or using pthreads.
-void *mt_rfid_run(void *ptr);
-
-//example
-/*
-
-pthread_t t;
-mt_rfid_t ufr = {READER_TYPE, PORT_NAME, PORT_INTERFACE, 0, 1};
 
-if (!pthread_create(&t, NULL, mt_rfid_run, (void *)&ufr)) {
-    getchar();
-    ufr.run = 0;
-    pthread_join(t, NULL);
-}
+#define ASYNC_SUFFIX 0
+#define ASYNC_BAUD_RATE 1000000
+#define BASYNC_BAUD_RATE B1000000
 
-*/
+// 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")
 
 #endif