]> rtime.felk.cvut.cz Git - coffee/mt-apps.git/blobdiff - mt_gpio.c
mt_server: Use "%s" format string in syslog()
[coffee/mt-apps.git] / mt_gpio.c
index 3176d778d0cdc081dff5686d1e025c2ed9b3337d..a10894f86374c601129931219e1aa53beda0bda4 100644 (file)
--- a/mt_gpio.c
+++ b/mt_gpio.c
-#include <stdio.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <unistd.h>
+#include <sys/stat.h>
 #include <fcntl.h>
-#include <termios.h>
-#include <sys/ioctl.h>
+#include <linux/input.h>
+#include <linux/input-event-codes.h>
 
-#include <uFCoder.h>
-
-#include "mt_rfid.h"
+#include "mt_gpio.h"
 #include "signal_exit.h"
+#include "json_helpers.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)
-{
-    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;
-    }
-
-    fprintf(stderr, "set %d rts %d\n", fd, level);
-
-    return 0;
-}
-
-static void set_baud_rate(int fd, int br) //TODO add some checking
-{
-    struct termios options;
-
-    tcgetattr(fd, &options);
-    cfsetispeed(&options, br);
-    cfsetospeed(&options, br);
-    tcsetattr(fd, TCSANOW, &options);
-}
-
-static int tty_open(const char *port, int br)
+static void gpio_cb(EV_P_ ev_io *w_, int revents)
 {
+    static char *type = "gpio";
 
-    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);
+    ev_io_gpio *w = (ev_io_gpio *)w_;
+    struct gpiod_line_event e;
+    int fd = w->fd;
+    char key = w->key;
 
-    return fd;
-}
-
-// really simple JSON helpers
-#define JSON_START()   dprintf(fd,"{")
-#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_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;
-
-    status = GetDlogicCardType(&card_type);
-    if (status != UFR_OK) {
-        fprintf(stderr, "GetDlogicCardType: %s\n", UFR_Status2String(status));
-        return;
-    }
-
-    status = GetCardIdEx(&sak, uid_bytes, &size);
-    if (status != UFR_OK) {
-        fprintf(stderr, "GetCardIdEx: %s\n", UFR_Status2String(status));
+    if (gpiod_line_event_read_fd(w->w.fd, &e) == -1) {
+        perror("gpiod_line_event_read_fd");
         return;
     }
 
-    JSON_PRINT();
-
-#ifdef UFR_BEEP
-    ReaderUISignal(0, 1); // no light, one beep
-#endif
+    JSON_START();
+    JSON_STR(type);
+    JSON_NEXT();
+    JSON_CHAR(key);
+    JSON_END();
 }
 
-#define UFR_ASYNC_SUFFIX 0 // keep it zero: separates uids, terminates strings
-
-static void ufr_cb(EV_P_ ev_io *w_, int revents)
+int mt_gpio_init(mt_gpio_t *self, struct ev_loop *loop, int fd)
 {
-    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);
+    struct gpiod_chip *chip;
+    struct gpiod_line *line;
+    ev_io_gpio *w;
+    int lfd;
+
+    size_t i;
+
+    for (i = 0; i < GPIO_COUNT; i++) {
+        chip = gpiod_chip_open_by_number(pins[i].chip);
+        if (!chip) {
+            perror("gpiod_chip_open");
+            break;
+        }
+        line = gpiod_chip_get_line(chip, pins[i].offset);
+        if (!line) {
+            gpiod_chip_close(chip);
+            perror("gpiod_chip_get_line");
+            break;
+        }
+        if (gpiod_line_event_request_rising(line, GPIO_CONSUMER, GPIO_ACTIVE_LOW) == -1) {
+            gpiod_chip_close(chip);
+            perror("gpiod_line_event_request_rising");
+            break;
+        }
+        lfd = gpiod_line_event_get_fd(line);
+        if (lfd == -1) {
+            perror("gpiod_line_event_get_fd");
+            gpiod_chip_close(chip);
+            break;
+        }
+
+        self->chip[i] = chip;
+        w = &(self->w[i]);
+        w->fd = fd;
+        w->key = pins[i].key;
+        ev_io_init(&(w->w), gpio_cb, lfd, EV_READ);
+        ev_io_start(loop, (ev_io *)w);
     }
-}
-
-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 -1;
-    }
-
-    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) {
+    if (i < GPIO_COUNT) {
+        for (size_t j = 0; j < i; j++) {
+            gpiod_chip_close(self->chip[j]);
+        }
         return -1;
     }
 
     return 0;
 }
 
-int mt_rfid_init(mt_rfid_t *self, struct ev_loop *loop, int fd)
+void mt_gpio_deinit(mt_gpio_t *self)
 {
-    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;
+    for (size_t i = 0; i < GPIO_COUNT; i++) {
+        gpiod_chip_close(self->chip[i]);
     }
-    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");
-    }
-
-    UFR_STATUS status = ReaderClose();
-    fprintf(stderr, "ReaderClose: %s\n", UFR_Status2String(status));
 }
 
 #ifndef NO_MAIN
 int main(int argc, char **argv)
 {
     struct ev_loop *loop = EV_DEFAULT;
-    mt_rfid_t rfid;
+    mt_gpio_t gpio;
 
     set_signal_exit(loop);
 
-    if (mt_rfid_init(&rfid, loop, STDOUT_FILENO) != 0) {
+    if (mt_gpio_init(&gpio, loop, STDOUT_FILENO) != 0) {
         return -1;
     }
 
     ev_run(loop, 0);
 
-    mt_rfid_deinit(&rfid);
+    mt_gpio_deinit(&gpio);
+    ev_loop_destroy(loop);
 
     return 0;
 }