taler-mdb

GNU Taler Extensions and Integrations
Log | Files | Refs | Submodules | README | LICENSE

commit da3d5efcb88504d6da0d9b9e68cbbca783f8d288
parent a426e984a92e04eabea4456751747267cf7f13cf
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Mon,  5 Feb 2024 17:13:51 +0100

new mdb: fix logging

Diffstat:
Msrc/Makefile.am | 9---------
Dsrc/taler-coin-acceptor.c | 503-------------------------------------------------------------------------------
Msrc/taler-mdb.c | 2+-
3 files changed, 1 insertion(+), 513 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am @@ -1,6 +1,5 @@ # This Makefile.am is in the public domain bin_PROGRAMS = \ - taler-coin-acceptor \ taler-mdb \ taler-mdb-display @@ -13,14 +12,6 @@ if USE_COVERAGE XLIB = -lgcov endif -taler_coin_acceptor_SOURCES = \ - taler-coin-acceptor.c -taler_coin_acceptor_LDADD = \ - -ltalermerchant \ - -ltalerutil \ - -lgnunetcurl \ - -lgnunetutil - taler_mdb_SOURCES = \ taler-mdb.c taler_mdb_LDADD = \ diff --git a/src/taler-coin-acceptor.c b/src/taler-coin-acceptor.c @@ -1,503 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - - You should have received a copy of the GNU General Public License -along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -*/ - -/** - * @brief Program to talk to the coin acceptor via USB-RS232. - * - * @author Christian Grothoff - */ -#include "config.h" -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <unistd.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> -#include <taler/taler_util.h> -#include <taler/taler_merchant_service.h> - - -/** - * File descriptor of the coin acceptor. - */ -static int fd = -1; - -/** - * Wrapper around #fd. - */ -static struct GNUNET_NETWORK_Handle *rf; - -/** - * Original terminal discipline. - */ -static struct termios uart_opts_backup; - -/** - * Our main task. - */ -static struct GNUNET_SCHEDULER_Task *tt; - -/** - * Return value from #main(). - */ -static int global_ret; - -/** - * Array mapping numbers to the value of the respective coin. - */ -static struct TALER_Amount coin_value[256]; - -/** - * What is our backend? - */ -static char *merchant_url; - -/** - * Context for making CURL requests. - */ -static struct GNUNET_CURL_Context *ctx; - -/** - * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule(). - */ -static struct GNUNET_CURL_RescheduleContext *rc; - -/** - * Handle used to issue the reward. - */ -static struct TALER_MERCHANT_RewardAuthorizeHandle *tah; - -/** - * Handle to watch for reward being picked up. - */ -static struct TALER_MERCHANT_RewardMerchantGetHandle *tmgh; - -/** - * Current sum. - */ -static struct TALER_Amount sum; - -/** - * Reward ID of the currently active reward. - */ -static struct TALER_RewardIdentifierP reward_id; - -/** - * Function run on shutdown. - * - * @param cls NULL - */ -static void -do_shutdown (void *cls) -{ - (void) cls; - - if (-1 != fd) - { - if (0 != tcsetattr (fd, - TCSAFLUSH, - &uart_opts_backup)) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "tcsetattr"); - } - GNUNET_break (0 == close (fd)); - fd = -1; - } - if (NULL != tt) - { - GNUNET_SCHEDULER_cancel (tt); - tt = NULL; - } - if (NULL != ctx) - { - GNUNET_CURL_fini (ctx); - ctx = NULL; - } - if (NULL != rc) - { - GNUNET_CURL_gnunet_rc_destroy (rc); - rc = NULL; - } - if (NULL != tah) - { - TALER_MERCHANT_reward_authorize_cancel (tah); - tah = NULL; - } - if (NULL != tmgh) - { - TALER_MERCHANT_merchant_reward_get_cancel (tmgh); - tmgh = NULL; - } - if (GNUNET_OK == - TALER_amount_is_valid (&sum)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "%s left in coin acceptor at shutdown\n", - TALER_amount2s (&sum)); - memset (&sum, 0, sizeof (sum)); - } - GNUNET_free (merchant_url); - GNUNET_free (rf); -} - - -/** - * With result of a GET /private/rewards/$REWARD_ID request - * - * @param cls closure - * @param tsr response details - */ -static void -pickup_cb ( - void *cls, - const struct TALER_MERCHANT_RewardStatusResponse *tsr) -{ - tmgh = NULL; - switch (tsr->hr.http_status) - { - case MHD_HTTP_OK: - if (0 == - TALER_amount_cmp (&sum, - &tsr->details.ok.total_picked_up)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Process completed\n"); - memset (&sum, - 0, - sizeof (sum)); - return; - } - /* Keep checking */ - tmgh = TALER_MERCHANT_merchant_reward_get (ctx, - merchant_url, - &reward_id, - NULL, - GNUNET_TIME_UNIT_ZERO, - false, - &pickup_cb, - NULL); - GNUNET_assert (NULL != tmgh); - return; - default: - GNUNET_break (0); /* FIXME: handle failures... */ - } -} - - -/** - * Callback for a /reserves/$RESERVE_PUB/reward-authorize request. Returns the result of - * the operation. - * - * @param cls closure, NULL - * @param tar response details - */ -static void -authorize_cb ( - void *cls, - const struct TALER_MERCHANT_RewardAuthorizeResponse *tar) -{ - const struct TALER_MERCHANT_HttpResponse *hr = &tar->hr; - - (void) cls; - tah = NULL; - switch (hr->http_status) - { - case MHD_HTTP_OK: - break; /* handled below */ - default: - GNUNET_break (0); // FIXME: handle cases! - return; - } - - // FIXME: show reward_uri on display! - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Reward pickup uri: %s\n", - tar->details.ok.reward_uri); - /* FIXME: merchant service to support long-polling here! */ - reward_id = tar->details.ok.reward_id; - tmgh = TALER_MERCHANT_merchant_reward_get (ctx, - merchant_url, - &tar->details.ok.reward_id, - NULL, - GNUNET_TIME_UNIT_ZERO, - false, - &pickup_cb, - NULL); - GNUNET_assert (NULL != tmgh); -} - - -/** - * Function run on coin insert. - * - * @param cls NULL - */ -static void -do_read (void *cls) -{ - char c = '\0'; - int ret; - - (void) cls; - tt = NULL; - ret = read (fd, - &c, - sizeof (c)); - if ( (1 == ret) && - (-1 != (int) c) ) - { - struct TALER_Amount *value = &coin_value[(unsigned char) c]; - - if (GNUNET_OK != - TALER_amount_is_valid (value)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Coin %d accepted by acceptor, but not configured!\n", - (int) c); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Coin %d of value %s accepted\n", - (int) c, - TALER_amount2s (value)); - if (GNUNET_OK != - TALER_amount_is_valid (&sum)) - sum = *value; - else - GNUNET_assert (0 <= - TALER_amount_add (&sum, - &sum, - value)); - if (NULL != tah) - { - TALER_MERCHANT_reward_authorize_cancel (tah); - tah = NULL; - } - /* FIXME: handle case where we INCREASE an - existing reward! (needs new backend API!) */ - tah = TALER_MERCHANT_reward_authorize (ctx, - merchant_url, - "taler://FIXME", - &sum, - "coin acceptor", - &authorize_cb, - NULL); - } - } - tt = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, - rf, - &do_read, - NULL); -} - - -/** - * Function to iterate over options in the "tca-map" section. - * - * @param cls closure - * @param section name of the section - * @param option name of the option - * @param value value of the option - */ -static void -map_builder (void *cls, - const char *section, - const char *option, - const char *value) -{ - char dummy; - unsigned int num; - - if (1 != sscanf (option, - "%u%c", - &num, - &dummy)) - { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, - section, - option, - "option name must be a number"); - return; - } - if (num > 255) - { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, - section, - option, - "option number must be below 256"); - return; - } - if (GNUNET_OK != - TALER_string_to_amount (value, - &coin_value[num])) - { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, - section, - option, - "option value must be an amount"); - return; - } -} - - -/** - * 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]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "call with TTY filename argument\n"); - global_ret = 1; - return; - } - GNUNET_CONFIGURATION_iterate_section_values (cfg, - "tca-map", - &map_builder, - NULL); - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "tca", - "BACKEND_URL", - &merchant_url)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, - "tca", - "BACKEND_URL"); - return; - } - ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, - &rc); - rc = GNUNET_CURL_gnunet_rc_create (ctx); - // FIXME: setup authentication based on cfg for ctx! - fd = open (argv[0], - O_RDONLY); - if (-1 == fd) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, - "open", - argv[0]); - GNUNET_free (merchant_url); - global_ret = 1; - return; - } - if (0 != tcgetattr (fd, - &uart_opts_backup)) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "tcgetattr"); - GNUNET_break (0 == close (fd)); - fd = -1; - global_ret = 1; - GNUNET_free (merchant_url); - return; - } - GNUNET_SCHEDULER_add_shutdown (&do_shutdown, - NULL); - tcflush (fd, - TCIOFLUSH); - if (0 != tcsetattr (fd, - TCSAFLUSH, - &uart_opts_raw)) - { - 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); -} - - -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 @@ -878,7 +878,7 @@ start_command (const char *command, GNUNET_array_append (argv, argc, NULL); - ret = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_NONE, + ret = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, NULL, NULL, NULL,