[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-mdb] branch master updated: -work on coin acceptor
From: |
gnunet |
Subject: |
[taler-taler-mdb] branch master updated: -work on coin acceptor |
Date: |
Sat, 23 Jul 2022 12:22:51 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository taler-mdb.
The following commit(s) were added to refs/heads/master by this push:
new 2881c2e -work on coin acceptor
2881c2e is described below
commit 2881c2e6fb5286eea3d452417700d9fae18a83ae
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Sat Jul 23 12:22:45 2022 +0200
-work on coin acceptor
---
configure.ac | 6 -
src/Makefile.am | 3 +
src/acceptor.conf | 14 +++
src/taler-coin-acceptor.c | 291 +++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 303 insertions(+), 11 deletions(-)
diff --git a/configure.ac b/configure.ac
index 1b9d517..a75ff34 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,15 +13,9 @@ AC_PROG_CC
# Checks for libraries.
AC_CHECK_LIB([nfc], [nfc_open])
-# Checks for libraries.
-AC_CHECK_LIB([usb], [libusb_init])
-
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h unistd.h sys/un.h netinet/in.h
netinet/ip.h])
-# Checks for header files.
-AC_CHECK_HEADERS([libusb-1.0/libusb.h])
-
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_TYPE_SIZE_T
diff --git a/src/Makefile.am b/src/Makefile.am
index cf53389..278a77a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,9 @@ endif
taler_coin_acceptor_SOURCES = \
taler-coin-acceptor.c
taler_coin_acceptor_LDADD = \
+ -ltalermerchant \
+ -ltalerutil \
+ -lgnunetcurl \
-lgnunetutil
taler_mdb_SOURCES = \
diff --git a/src/acceptor.conf b/src/acceptor.conf
new file mode 100644
index 0000000..2edc5a3
--- /dev/null
+++ b/src/acceptor.conf
@@ -0,0 +1,14 @@
+# This file is in the public domain.
+
+# sample configuration for the taler-coin-acceptor
+
+[tca-map]
+1 = CHF:0.1
+2 = CHF:0.2
+5 = CHF:0.5
+10 = CHF:1
+20 = CHF:2
+50 = CHF:5
+
+[tca]
+BACKEND_URL = https://backend.chf.taler.net/
diff --git a/src/taler-coin-acceptor.c b/src/taler-coin-acceptor.c
index 3f0f1ef..2e917e0 100644
--- a/src/taler-coin-acceptor.c
+++ b/src/taler-coin-acceptor.c
@@ -33,6 +33,8 @@ along with
#include <fcntl.h>
#include <termios.h>
#include <gnunet/gnunet_util_lib.h>
+#include <taler/taler_util.h>
+#include <taler/taler_merchant_service.h>
/**
@@ -60,6 +62,46 @@ static struct GNUNET_SCHEDULER_Task *tt;
*/
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 tip.
+ */
+static struct TALER_MERCHANT_TipAuthorizeHandle *tah;
+
+/**
+ * Handle to watch for tip being picked up.
+ */
+static struct TALER_MERCHANT_TipMerchantGetHandle *tmgh;
+
+/**
+ * Current sum.
+ */
+static struct TALER_Amount sum;
+
+/**
+ * Tip ID of the currently active tip.
+ */
+static struct TALER_TipIdentifierP tip_id;
+
/**
* Function run on shutdown.
*
@@ -87,10 +129,140 @@ do_shutdown (void *cls)
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_tip_authorize_cancel (tah);
+ tah = NULL;
+ }
+ if (NULL != tmgh)
+ {
+ TALER_MERCHANT_merchant_tip_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/tips/$TIP_ID request
+ *
+ * @param cls closure
+ * @param hr HTTP response details
+ * @param total_authorized how many tips were authorized under this tip
+ * @param total_picked_up how many tips have been picked up
+ * @param reason what was the reason given for the tip
+ * @param expiration when the tip will expire
+ * @param reserve_pub which reserve is funding this tip
+ * @param pickups_length length of the @a pickups array
+ * @param pickups array of pickup operations performed for this tip
+ */
+static void
+pickup_cb (
+ void *cls,
+ const struct TALER_MERCHANT_HttpResponse *hr,
+ const struct TALER_Amount *total_authorized,
+ const struct TALER_Amount *total_picked_up,
+ const char *reason,
+ struct GNUNET_TIME_Timestamp expiration,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ unsigned int pickups_length,
+ const struct TALER_MERCHANT_PickupDetail pickups[])
+{
+ tmgh = NULL;
+ switch (hr->http_status)
+ {
+ case MHD_HTTP_OK:
+ if (0 == TALER_amount_cmp (&sum,
+ total_picked_up))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Process completed\n");
+ memset (&sum,
+ 0,
+ sizeof (sum));
+ return;
+ }
+ /* Keep checking */
+ tmgh = TALER_MERCHANT_merchant_tip_get (ctx,
+ merchant_url,
+ &tip_id,
+ false,
+ &pickup_cb,
+ NULL);
+ GNUNET_assert (NULL != tmgh);
+ return;
+ default:
+ GNUNET_break (0); /* FIXME: handle failures... */
+ }
+}
+
+
+/**
+ * Callback for a /reserves/$RESERVE_PUB/tip-authorize request. Returns the
result of
+ * the operation.
+ *
+ * @param cls closure, NULL
+ * @param hr HTTP response details
+ * @param tip_idp which tip ID should be used to pickup the tip
+ * @param tip_uri URI for the tip
+ * @param tip_expiration when does the tip expire
+ */
+static void
+authorize_cb (
+ void *cls,
+ const struct TALER_MERCHANT_HttpResponse *hr,
+ struct TALER_TipIdentifierP *tip_idp,
+ const char *tip_uri,
+ struct GNUNET_TIME_Timestamp tip_expiration)
+{
+ (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 tip_uri on display!
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Tip pickup uri: %s\n",
+ tip_uri);
+ /* FIXME: update API to enable long-polling here! */
+ tip_id = *tip_idp;
+ tmgh = TALER_MERCHANT_merchant_tip_get (ctx,
+ merchant_url,
+ &tip_id,
+ false,
+ &pickup_cb,
+ NULL);
+ GNUNET_assert (NULL != tmgh);
+}
+
+
+
/**
* Function run on coin insert.
*
@@ -103,13 +275,51 @@ do_read (void *cls)
int ret;
(void) cls;
- ret = read (fd, &c, 1);
- if ( (0 != ret) &&
+ tt = NULL;
+ ret = read (fd,
+ &c,
+ sizeof (c));
+ if ( (1 == ret) &&
(-1 != (int) c) )
{
- fprintf (stdout,
- "%d\n",
- (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_tip_authorize_cancel (tah);
+ tah = NULL;
+ }
+ /* FIXME: handle case where we INCREASE an
+ existing tip! (needs new backend API!) */
+ tah = TALER_MERCHANT_tip_authorize (ctx,
+ merchant_url,
+ "taler://FIXME",
+ &sum,
+ "coin acceptor",
+ &authorize_cb,
+ NULL);
+ }
}
tt = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
rf,
@@ -118,6 +328,55 @@ do_read (void *cls)
}
+/**
+ * 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.
*
@@ -165,6 +424,26 @@ run (void *cls,
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)
@@ -172,6 +451,7 @@ run (void *cls,
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"open",
argv[0]);
+ GNUNET_free (merchant_url);
global_ret = 1;
return;
}
@@ -183,6 +463,7 @@ run (void *cls,
GNUNET_break (0 == close (fd));
fd = -1;
global_ret = 1;
+ GNUNET_free (merchant_url);
return;
}
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-taler-mdb] branch master updated: -work on coin acceptor,
gnunet <=