summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <grothoff@gnunet.org>2022-07-22 16:22:59 +0200
committerChristian Grothoff <grothoff@gnunet.org>2022-07-22 16:22:59 +0200
commitaa66904d79bb3ce13e32689b45dbd416d4a73fc7 (patch)
tree84380c8e60a621cb2a68c86e4f79fc9077854bba
parent3c5d8d40c75700cd96c14cb2f93b12d4bb2e7aa3 (diff)
downloadtaler-mdb-aa66904d79bb3ce13e32689b45dbd416d4a73fc7.tar.gz
taler-mdb-aa66904d79bb3ce13e32689b45dbd416d4a73fc7.tar.bz2
taler-mdb-aa66904d79bb3ce13e32689b45dbd416d4a73fc7.zip
use tty directly for coin acceptor, build event loop
-rw-r--r--src/Makefile.am2
-rw-r--r--src/taler-coin-acceptor.c333
-rw-r--r--src/taler-mdb.c2
3 files changed, 176 insertions, 161 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 86ddd3b..cf53389 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,7 +15,7 @@ endif
taler_coin_acceptor_SOURCES = \
taler-coin-acceptor.c
taler_coin_acceptor_LDADD = \
- -lusb-1.0
+ -lgnunetutil
taler_mdb_SOURCES = \
taler-mdb.c
diff --git a/src/taler-coin-acceptor.c b/src/taler-coin-acceptor.c
index fde4a8a..3f0f1ef 100644
--- a/src/taler-coin-acceptor.c
+++ b/src/taler-coin-acceptor.c
@@ -27,196 +27,211 @@ along with
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
-#include <arpa/inet.h>
-#include <libusb-1.0/libusb.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <gnunet/gnunet_util_lib.h>
-// FIXME: make this configurable later...
-/* future technology devices international */
-#define VENDOR_ID 0x0403
-/* FT232 Serial UART IC */
-#define PRODUCT_ID 0x6001
-
-#define USB_CTL_REQ_SET_LINE_CODING 0x20
-
-#define LEO_ONE_STOP_BIT 0x00
-#define LEO_ONEHALF_STOP_BIT 0x01
-#define LEO_TWO_STOP_BIT 0x02
-
-#define LEO_PARITY_NONE 0x00
-#define LEO_PARITY_ODD 0x01
-#define LEO_PARITY_EVEN 0x02
-#define LEO_PARITY_MARK 0x03
-#define LEO_PARITY_SPACE 0x04
+/**
+ * File descriptor of the coin acceptor.
+ */
+static int fd = -1;
-#define ACM_CTRL_DTR 0x01
-#define ACM_CTRL_RTS 0x02
+/**
+ * Wrapper around #fd.
+ */
+static struct GNUNET_NETWORK_Handle *rf;
/**
- * Handle to USB device.
+ * Original terminal discipline.
*/
-static struct libusb_device_handle *device_handle;
+static struct termios uart_opts_backup;
-/* The Endpoint address are hard coded. You should use lsusb -v to find
- * the values corresponding to your device.
+/**
+ * Our main task.
*/
-static int ep_in_addr = 0x83;
-static int ep_out_addr = 0x02;
+static struct GNUNET_SCHEDULER_Task *tt;
+/**
+ * Return value from #main().
+ */
+static int global_ret;
-static int
-read_char (void)
+/**
+ * Function run on shutdown.
+ *
+ * @param cls NULL
+ */
+static void
+do_shutdown (void *cls)
{
- int actual_length;
- unsigned char data;
- int rc;
-
- rc = libusb_bulk_transfer (device_handle,
- ep_in_addr,
- &data,
- sizeof (data),
- &actual_length,
- 1000 /* timeout? */);
- if (rc == LIBUSB_ERROR_TIMEOUT)
+ (void) cls;
+
+ if (-1 != fd)
{
- fprintf (stderr,
- "TIMEOUT\n");
- return EOF;
+ if (0 != tcsetattr (fd,
+ TCSAFLUSH,
+ &uart_opts_backup))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "tcsetattr");
+ }
+ GNUNET_break (0 == close (fd));
+ fd = -1;
}
- if (rc < 0)
+ if (NULL != tt)
{
- fprintf (stderr,
- "Error %s while waiting for char\n",
- libusb_error_name (rc));
- return EOF;
+ GNUNET_SCHEDULER_cancel (tt);
+ tt = NULL;
}
- return data;
+ GNUNET_free (rf);
}
-int
-main (int argc,
- char **argv)
+/**
+ * Function run on coin insert.
+ *
+ * @param cls NULL
+ */
+static void
+do_read (void *cls)
{
- int rc;
+ char c = '\0';
+ int ret;
- rc = libusb_init (NULL);
- if (rc < 0)
+ (void) cls;
+ ret = read (fd, &c, 1);
+ if ( (0 != ret) &&
+ (-1 != (int) c) )
{
- fprintf (stderr,
- "Error initializing usb: %s\n",
- libusb_error_name (rc));
- return 1;
+ fprintf (stdout,
+ "%d\n",
+ (int) c);
}
+ tt = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+ rf,
+ &do_read,
+ NULL);
+}
- libusb_set_debug (NULL,
- 3);
- device_handle = libusb_open_device_with_vid_pid (NULL,
- VENDOR_ID,
- PRODUCT_ID);
- if (NULL == device_handle)
- {
- fprintf (stderr,
- "Error finding USB device\n");
- libusb_exit (NULL);
- return 1;
- }
- /* Maybe there is someone else attached, detach other drivers from
- all the USB interfaces. NOTE: not sure if there are *2*! */
- for (int if_num = 0; if_num < 2; if_num++)
+/**
+ * Function run on startup.
+ *
+ * @param cls NULL
+ * @param args arguments left
+ * @param cfgfile config file name
+ * @param cfg handle for the configuration file
+ */
+static void
+run (void *cls,
+ char *const *argv,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct termios uart_opts_raw;
+
+ (void) cls;
+ /* reset current uart discipline */
+ memset (&uart_opts_raw,
+ 0,
+ sizeof(uart_opts_raw));
+
+ /* set baudrate */
+ cfsetispeed (&uart_opts_raw, B4800);
+ cfsetospeed (&uart_opts_raw, B4800);
+
+ /* set options */
+ uart_opts_raw.c_cflag &= ~PARENB;
+ uart_opts_raw.c_cflag &= ~CSTOPB;
+ uart_opts_raw.c_cflag &= ~CSIZE;
+ uart_opts_raw.c_cflag |= CS8;
+
+ /* 19200 bps, 8 databits, ignore cd-signal, allow reading */
+ uart_opts_raw.c_cflag |= (CLOCAL | CREAD);
+ uart_opts_raw.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+ uart_opts_raw.c_iflag = IGNPAR;
+ uart_opts_raw.c_oflag &= ~OPOST;
+ uart_opts_raw.c_cc[VMIN] = 0;
+ uart_opts_raw.c_cc[VTIME] = 50;
+
+ if (NULL == argv[0])
{
- if (libusb_kernel_driver_active (device_handle,
- if_num))
- {
- libusb_detach_kernel_driver (device_handle,
- if_num);
- }
- rc = libusb_claim_interface (device_handle,
- if_num);
- if (rc < 0)
- {
- fprintf (stderr,
- "Error claiming interface: %s\n",
- libusb_error_name (rc));
- libusb_close (device_handle);
- libusb_exit (NULL);
- return 1;
- }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "call with TTY filename argument\n");
+ global_ret = 1;
+ return;
}
-#if 1
- rc = libusb_control_transfer (device_handle,
- 0x21,
- 0x22,
- ACM_CTRL_DTR | ACM_CTRL_RTS,
- 0,
- NULL,
- 0,
- 0);
- if (rc < 0)
+ fd = open (argv[0],
+ O_RDONLY);
+ if (-1 == fd)
{
- fprintf (stderr,
- "Error during control transfer: %s\n",
- libusb_error_name (rc));
- libusb_close (device_handle);
- libusb_exit (NULL);
- return 1;
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "open",
+ argv[0]);
+ global_ret = 1;
+ return;
}
-#endif
-
- /* - set line encoding: here 9600 8N1
- * 9600 = 0x2580 ~> 0x80, 0x25 in little endian
- */
+ if (0 != tcgetattr (fd,
+ &uart_opts_backup))
{
- struct LineEncodingOptions
- {
- /**
- * In *little* endian.
- */
- uint32_t baud_rate;
- uint8_t b_char_format;
- uint8_t b_parity_type;
- uint8_t b_data_bits;
- } leo = {
- .baud_rate = __builtin_bswap32 (htonl (4800)),
- .b_char_format = LEO_ONE_STOP_BIT,
- .b_parity_type = LEO_PARITY_ODD,
- .b_data_bits = 0x08
- };
-
- rc = libusb_control_transfer (device_handle,
- 0x21,
- USB_CTL_REQ_SET_LINE_CODING,
- 0,
- 0,
- (unsigned char *) &leo,
- sizeof(leo),
- 0);
- if (rc < 0)
- {
- fprintf (stderr,
- "Error during control transfer: %s\n",
- libusb_error_name (rc));
- libusb_close (device_handle);
- libusb_exit (NULL);
- return 1;
- }
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "tcgetattr");
+ GNUNET_break (0 == close (fd));
+ fd = -1;
+ global_ret = 1;
+ return;
}
-
- /* FIXME: proper event loop... */
- while (1)
+ GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+ NULL);
+ tcflush (fd,
+ TCIOFLUSH);
+ if (0 != tcsetattr (fd,
+ TCSAFLUSH,
+ &uart_opts_raw))
{
- int in = read_char ();
-
- if (-1 != in)
- fprintf (stdout,
- "Received: %d\n",
- in);
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "tcsetattr");
+ GNUNET_SCHEDULER_shutdown ();
+ global_ret = 1;
+ return;
}
+ rf = GNUNET_NETWORK_socket_box_native (fd);
+ tt = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+ rf,
+ &do_read,
+ NULL);
+}
- libusb_release_interface (device_handle,
- 0);
- libusb_close (device_handle);
- libusb_exit (NULL);
- return 0;
+
+int
+main (int argc,
+ char *const*argv)
+{
+ /* the available command line options */
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+ enum GNUNET_GenericReturnValue ret;
+
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_get_utf8_args (argc, argv,
+ &argc, &argv))
+ return 4;
+ ret = GNUNET_PROGRAM_run (argc,
+ argv,
+ "taler-mdb",
+ "This is an application for snack machines to pay with GNU Taler via NFC.\n",
+ options,
+ &run,
+ NULL);
+ GNUNET_free_nz ((void *) argv);
+ if (GNUNET_NO == ret)
+ return 0;
+ if (GNUNET_OK != ret)
+ return 1;
+ return global_ret;
}
diff --git a/src/taler-mdb.c b/src/taler-mdb.c
index f0b1529..0e2d6d8 100644
--- a/src/taler-mdb.c
+++ b/src/taler-mdb.c
@@ -3065,7 +3065,7 @@ mdb_init (void)
* @param cls closure
* @param args arguments left
* @param cfgfile config file name
- * @param cfg handle for the configuration file
+ * @param cfg handle for the configuration
*/
static void
run (void *cls,