summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-05-09 14:37:46 +0200
committerChristian Grothoff <christian@grothoff.org>2022-05-09 14:37:46 +0200
commit2ead95eadce935dc95c8b6a3305e711d2b30561e (patch)
treed0cf64fa01fb486741507371cf41f3f69102fb09 /src
parent108bba2e83ddcc705fe506551253852f6ca7da41 (diff)
downloadtaler-mdb-2ead95eadce935dc95c8b6a3305e711d2b30561e.tar.gz
taler-mdb-2ead95eadce935dc95c8b6a3305e711d2b30561e.tar.bz2
taler-mdb-2ead95eadce935dc95c8b6a3305e711d2b30561e.zip
add support for multi-backend multi-currency deployments
Diffstat (limited to 'src')
-rw-r--r--src/main.c417
1 files changed, 244 insertions, 173 deletions
diff --git a/src/main.c b/src/main.c
index 42da955..b2c5891 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2019, 2020 Taler Systems SA
+ Copyright (C) 2019, 2020, 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
@@ -58,6 +58,11 @@ along with
/* for adafruit pitft display */
#include <linux/fb.h>
+#ifndef EXIT_NOTCONFIGURED
+#define EXIT_NOTCONFIGURED 6
+#endif
+
+
/* Constants */
#define MAX_SIZE_RX_BUFFER 256
@@ -292,6 +297,11 @@ struct Product
char *description;
/**
+ * Authorization to header to use for this @e instance.
+ */
+ char *auth_header;
+
+ /**
* Which instance should be used for billing? Full URL, replaces
* the default base URL for orders involving this product. NULL if
* we should use the #backend_base_url.
@@ -313,7 +323,7 @@ struct Product
* Set to #GNUNET_YES if this product was found
* to have been sold out (VEND failure).
*/
- int sold_out;
+ bool sold_out;
/**
* Key for the product (optional, needed to test the application without vending machine)
@@ -328,6 +338,17 @@ struct Product
*/
struct PaymentActivity
{
+
+ /**
+ * Curl context for communication with taler backend
+ */
+ struct GNUNET_CURL_Context *ctx;
+
+ /**
+ * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule().
+ */
+ struct GNUNET_CURL_RescheduleContext *rc;
+
/**
* Handle to a POST /orders operation
*/
@@ -390,16 +411,15 @@ struct PaymentActivity
/**
* Member to see if the wallet already received a uri
- * GNUNET_YES, GNUNET_NO
- * If yes, tunneling can be offered to the wallet
+ * If true, tunneling can be offered to the wallet.
*/
- int wallet_has_uri;
+ bool wallet_has_uri;
/**
- * Set to #GNUNET_YES once the product has been paid
+ * Set to true once the product has been paid
* (and we are in the process of yielding the product).
*/
- int paid;
+ bool paid;
};
@@ -468,7 +488,7 @@ struct MdbHandle
/**
* Indicates if a vend session is running or not
*/
- int session_running;
+ bool session_running;
/**
* File descriptor to the UART device file
@@ -542,6 +562,16 @@ struct Refund
struct Refund *prev;
/**
+ * Curl context for communication with taler backend
+ */
+ struct GNUNET_CURL_Context *ctx;
+
+ /**
+ * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule().
+ */
+ struct GNUNET_CURL_RescheduleContext *rc;
+
+ /**
* Handle to the ongoing operation.
*/
struct TALER_MERCHANT_OrderRefundHandle *orh;
@@ -578,7 +608,7 @@ static int in_shutdown;
* Flag set to remember that MDB needs shutdown
* (because we were actually able to talk to MDB).
*/
-static int mdb_active;
+static bool mdb_active;
/**
* Reference to the keyboard task
@@ -591,21 +621,6 @@ static struct GNUNET_SCHEDULER_Task *keyboard_task;
static struct GNUNET_SCHEDULER_Task *cancelbutton_task;
/**
- * Curl context for communication with taler backend
- */
-static struct GNUNET_CURL_Context *ctx;
-
-/**
- * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule().
- */
-static struct GNUNET_CURL_RescheduleContext *rc;
-
-/**
- * Currency read from configuration file
- */
-static char *currency;
-
-/**
* Taler Backend url read from configuration file
*/
static char *backend_base_url;
@@ -616,11 +631,6 @@ static char *backend_base_url;
static char *fulfillment_msg;
/**
- * Authorization for the taler backend
- */
-static char *authorization;
-
-/**
* ESSID of a WLAN network offered by the snack system, or NULL.
*/
static char *essid;
@@ -756,6 +766,11 @@ static int disable_tty;
static int sold_out_enabled;
/**
+ * True if we have the 'reset' button on GPIO.
+ */
+static bool have_gpio;
+
+/**
* Taler wallet application identifier
*/
static const uint8_t taler_aid[] = { 0xF0, 0x00, 0x54, 0x41, 0x4c, 0x45, 0x52 };
@@ -915,6 +930,25 @@ run_mdb_event_loop (void);
/**
+ * Runs asynchronous cleanup part for freeing a
+ * payment activity.
+ *
+ * @param[in] cls a `struct PaymentActivity` to clean up
+ */
+static void
+async_pa_cleanup_job (void *cls)
+{
+ struct PaymentActivity *pa = cls;
+
+ if (NULL != pa->ctx)
+ GNUNET_CURL_fini (pa->ctx);
+ if (NULL != pa->rc)
+ GNUNET_CURL_gnunet_rc_destroy (pa->rc);
+ GNUNET_free (pa);
+}
+
+
+/**
* @brief Cleanup all the data when a order has succeeded or got cancelled
*
* @param pa the payment activity to clean up
@@ -928,15 +962,12 @@ cleanup_payment (struct PaymentActivity *pa)
nfc_close (pa->pnd);
}
if (NULL != cancelbutton_task)
- {
GNUNET_SCHEDULER_cancel (cancelbutton_task);
- cancelbutton_task = NULL;
- }
if (NULL != pa->po)
TALER_MERCHANT_orders_post_cancel (pa->po);
if (NULL != pa->ogh)
TALER_MERCHANT_merchant_order_get_cancel (pa->ogh);
- GNUNET_CURL_gnunet_scheduler_reschedule (&rc);
+ GNUNET_CURL_gnunet_scheduler_reschedule (&pa->rc);
if (NULL != pa->task)
GNUNET_SCHEDULER_cancel (pa->task);
if (NULL != pa->delay_task)
@@ -959,7 +990,8 @@ cleanup_payment (struct PaymentActivity *pa)
GNUNET_free (pa->taler_pay_uri);
}
GNUNET_free (pa->order_id);
- GNUNET_free (pa);
+ GNUNET_SCHEDULER_add_now (&async_pa_cleanup_job,
+ pa);
}
@@ -1047,19 +1079,8 @@ shutdown_task (void *cls)
/* last ditch saying nicely goodbye to MDB */
in_shutdown = GNUNET_YES;
mdb.cmd = &endSession;
- run_mdb_event_loop ();
-
- if (NULL != ctx)
- {
- GNUNET_CURL_fini (ctx);
- ctx = NULL;
- }
- if (NULL != rc)
- {
- GNUNET_CURL_gnunet_rc_destroy (rc);
- rc = NULL;
- }
-
+ if (-1 != mdb.uartfd)
+ run_mdb_event_loop ();
if ( (MAP_FAILED != qrDisplay.memory) &&
(NULL != qrDisplay.memory) )
{
@@ -1082,12 +1103,13 @@ shutdown_task (void *cls)
GNUNET_break (0 == close (qrDisplay.backlightfd));
qrDisplay.backlightfd = -1;
}
- if (0 < cancel_button.cancelbuttonfd)
+ if (-1 != cancel_button.cancelbuttonfd)
{
- GNUNET_break (0 == close (cancel_button.cancelbuttonfd));
+ GNUNET_break (0 ==
+ close (cancel_button.cancelbuttonfd));
cancel_button.cancelbuttonfd = open ("/sys/class/gpio/unexport",
O_WRONLY);
- if (0 > cancel_button.cancelbuttonfd)
+ if (-1 == cancel_button.cancelbuttonfd)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unable to open /gpio/unexport for cancel button\n");
@@ -1104,6 +1126,7 @@ shutdown_task (void *cls)
}
GNUNET_break (0 == close (cancel_button.cancelbuttonfd));
+ cancel_button.cancelbuttonfd = -1;
}
}
/* free the allocated productes read from config file */
@@ -1112,6 +1135,7 @@ shutdown_task (void *cls)
for (unsigned int i = 0; i < products_length; i++)
{
GNUNET_free (products[i].description);
+ GNUNET_free (products[i].auth_header);
GNUNET_free (products[i].instance);
GNUNET_free (products[i].preview);
}
@@ -1186,7 +1210,7 @@ wallet_transmit_uri (void *cls)
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"'PUT DATA' command sent successfully via NFC\n");
- pa->wallet_has_uri = GNUNET_YES;
+ pa->wallet_has_uri = true;
/* FIXME: or just offer Internet service here? */
/* transmit the uri again later, there can be many external failures,
@@ -1406,7 +1430,7 @@ check_payment_cb (void *cls,
if (TALER_MERCHANT_OSC_PAID == osr->status)
{
mdb.cmd = &cmd_approve_vend;
- payment_activity->paid = GNUNET_YES;
+ payment_activity->paid = true;
run_mdb_event_loop ();
if ((disable_mdb) && (! disable_tty))
{
@@ -1463,7 +1487,7 @@ check_payment_again (void *cls)
pa->delay_pay_task = NULL;
GNUNET_assert (NULL == pa->ogh);
- pa->ogh = TALER_MERCHANT_merchant_order_get (ctx,
+ pa->ogh = TALER_MERCHANT_merchant_order_get (pa->ctx,
pa->base_url,
pa->order_id,
NULL /* snack machine, no Web crap */,
@@ -1509,7 +1533,7 @@ proposal_cb (void *cls,
"Backend successfully created order `%s'\n",
por->details.ok.order_id);
pa->order_id = GNUNET_strdup (por->details.ok.order_id);
- pa->ogh = TALER_MERCHANT_merchant_order_get (ctx,
+ pa->ogh = TALER_MERCHANT_merchant_order_get (pa->ctx,
pa->base_url,
pa->order_id,
NULL /* snack machine, no Web crap */,
@@ -1523,6 +1547,7 @@ proposal_cb (void *cls,
static void
start_read_cancel_button (void);
+
/**
* @brief Launch a new order
*
@@ -1601,13 +1626,19 @@ launch_payment (struct Product *product)
? backend_base_url
: product->instance);
pa = GNUNET_new (struct PaymentActivity);
+ pa->ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
+ &pa->rc);
+ pa->rc = GNUNET_CURL_gnunet_rc_create (pa->ctx);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CURL_append_header (pa->ctx,
+ product->auth_header));
pa->product = product;
pa->amount = product->price;
/* put the order on the merchant's backend */
pa->base_url = (NULL == product->instance)
? backend_base_url
: product->instance;
- pa->po = TALER_MERCHANT_orders_post2 (ctx,
+ pa->po = TALER_MERCHANT_orders_post2 (pa->ctx,
pa->base_url,
orderReq,
MAX_REFUND_DELAY,
@@ -1624,11 +1655,11 @@ launch_payment (struct Product *product)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"TALER_MERCHANT_order_put failed (out of memory?)\n");
- GNUNET_free (pa);
+ cleanup_payment (pa);
return NULL;
}
/* Start to read the button on the VM to cancel this payment */
- if (0 < cancel_button.cancelbuttonfd)
+ if (-1 != cancel_button.cancelbuttonfd)
start_read_cancel_button ();
return pa;
}
@@ -1652,6 +1683,25 @@ vend_success ()
/**
+ * Runs asynchronous cleanup part for freeing a
+ * refund activity.
+ *
+ * @param[in] cls a `struct Refund` to clean up
+ */
+static void
+async_refund_cleanup_job (void *cls)
+{
+ struct Refund *r = cls;
+
+ if (NULL != r->ctx)
+ GNUNET_CURL_fini (r->ctx);
+ if (NULL != r->rc)
+ GNUNET_CURL_gnunet_rc_destroy (r->rc);
+ GNUNET_free (r);
+}
+
+
+/**
* @brief Callback to process a POST /refund request
*
* @param cls closure
@@ -1680,7 +1730,8 @@ refund_complete_cb (void *cls,
GNUNET_CONTAINER_DLL_remove (refund_head,
refund_tail,
r);
- GNUNET_free (r);
+ GNUNET_SCHEDULER_add_now (&async_refund_cleanup_job,
+ r);
}
@@ -1702,11 +1753,17 @@ vend_failure (void)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received MDB vend failure for `%s', refunding customer\n",
p->description);
- p->sold_out = GNUNET_YES;
+ p->sold_out = true;
mdb.cmd = &endSession;
- mdb.session_running = GNUNET_NO;
+ mdb.session_running = false;
r = GNUNET_new (struct Refund);
- r->orh = TALER_MERCHANT_post_order_refund (ctx,
+ r->ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
+ &r->rc);
+ r->rc = GNUNET_CURL_gnunet_rc_create (r->ctx);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CURL_append_header (r->ctx,
+ p->auth_header));
+ r->orh = TALER_MERCHANT_post_order_refund (r->ctx,
(NULL == p->instance)
? backend_base_url
: p->instance,
@@ -1766,14 +1823,14 @@ read_keyboard_command (void *cls)
else
{
mdb.cmd = &endSession;
- mdb.session_running = GNUNET_NO;
+ mdb.session_running = false;
}
run_mdb_event_loop ();
cleanup_payment (payment_activity);
payment_activity = NULL;
break;
case 'a':
- payment_activity->paid = GNUNET_YES;
+ payment_activity->paid = true;
mdb.cmd = &cmd_approve_vend;
run_mdb_event_loop ();
break;
@@ -1819,7 +1876,7 @@ read_keyboard_command (void *cls)
if (((char) input) == products[i].key)
{
if ( (sold_out_enabled) &&
- (GNUNET_YES == products[i].sold_out) )
+ (products[i].sold_out) )
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Product %s sold out, denying vend\n",
@@ -1885,7 +1942,7 @@ cancel_button_pressed (void *cls)
/* The order was paid and if we know this, then it is also yielded,
* just end the current session */
mdb.cmd = &endSession;
- mdb.session_running = GNUNET_NO;
+ mdb.session_running = false;
}
run_mdb_event_loop ();
cleanup_payment (payment_activity);
@@ -1944,7 +2001,9 @@ start_read_keyboard ()
static void
start_read_cancel_button ()
{
- struct GNUNET_DISK_FileHandle fh = { cancel_button.cancelbuttonfd };
+ struct GNUNET_DISK_FileHandle fh = {
+ cancel_button.cancelbuttonfd
+ };
GNUNET_assert (NULL == cancelbutton_task);
cancelbutton_task = GNUNET_SCHEDULER_add_read_file (
@@ -2071,10 +2130,10 @@ static void
handle_ack ()
{
if (&cmd_begin_session == mdb.last_cmd)
- mdb.session_running = GNUNET_YES;
+ mdb.session_running = true;
if (&cmd_deny_vend == mdb.last_cmd)
{
- mdb.session_running = GNUNET_NO;
+ mdb.session_running = false;
mdb.cmd = &endSession;
}
if (&cmd_reader_display_sold_out == mdb.last_cmd)
@@ -2190,7 +2249,7 @@ handle_command (const char *hex,
}
unsigned int product;
- GNUNET_break (GNUNET_YES == mdb.session_running);
+ GNUNET_break (mdb.session_running);
/* NOTE: hex[4..7] contain the price */
if (12 > hex_len)
{
@@ -2216,7 +2275,7 @@ handle_command (const char *hex,
"Product %u selected on MDB\n",
product);
if ( (sold_out_enabled) &&
- (GNUNET_YES == products[i].sold_out) )
+ (products[i].sold_out) )
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Product %s sold out, denying vend\n",
@@ -2236,12 +2295,12 @@ handle_command (const char *hex,
break;
}
case VMC_VEND_SUCCESS:
- GNUNET_break (GNUNET_YES == mdb.session_running);
+ GNUNET_break (mdb.session_running);
vend_success ();
break;
case VMC_VEND_FAILURE:
{
- GNUNET_break (GNUNET_YES == mdb.session_running);
+ GNUNET_break (mdb.session_running);
vend_failure ();
break;
}
@@ -2249,7 +2308,7 @@ handle_command (const char *hex,
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received MDB session complete\n");
- mdb.session_running = GNUNET_NO;
+ mdb.session_running = false;
mdb.cmd = &endSession;
if (NULL != payment_activity)
{
@@ -2389,7 +2448,7 @@ handle_command (const char *hex,
case VMC_READER_DISABLE:
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received Reader Disable via MDB\n");
- mdb.session_running = GNUNET_NO;
+ mdb.session_running = false;
if (NULL != payment_activity)
{
cleanup_payment (payment_activity);
@@ -2400,23 +2459,23 @@ handle_command (const char *hex,
if ( (sold_out_enabled) &&
(0 != strcmp (products[i].description,
"empty")) &&
- (GNUNET_YES == products[i].sold_out) )
+ (products[i].sold_out) )
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Resetting sold out state of product %s\n",
products[i].description);
- products[i].sold_out = GNUNET_NO;
+ products[i].sold_out = false;
}
}
break;
case VMC_READER_ENABLE:
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received Reader Enable via MDB\n");
- mdb.session_running = GNUNET_NO;
+ mdb.session_running = false;
break;
case VMC_READER_CANCEL:
mdb.cmd = &cmd_reader_cancelled;
- mdb.session_running = GNUNET_NO;
+ mdb.session_running = false;
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -2441,7 +2500,7 @@ handle_command (const char *hex,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Received command out of sequence from MDB (for command `%s')\n",
(NULL != mdb.last_cmd) ? mdb.last_cmd->name : "?");
- mdb.session_running = GNUNET_NO;
+ mdb.session_running = false;
if (mdb.last_cmd != &endSession)
mdb.cmd = &endSession;
else
@@ -2496,7 +2555,7 @@ read_mdb_command (void *cls)
while (mdb.rx_off > 0)
{
- mdb_active = GNUNET_YES;
+ mdb_active = true;
/* find beginning of command */
for (cmdStartIdx = 0; cmdStartIdx < mdb.rx_off; cmdStartIdx++)
if (VMC_CMD_START == mdb.rxBuffer[cmdStartIdx])
@@ -2555,7 +2614,7 @@ run_mdb_event_loop ()
struct GNUNET_DISK_FileHandle fh = { mdb.uartfd };
/* begin session if no cmd waits for sending and no cmd is received from the VMC */
- if ( (GNUNET_NO == mdb.session_running) &&
+ if ( (! mdb.session_running) &&
(NULL == mdb.cmd) &&
(NULL == mdb.last_cmd) )
{
@@ -2609,6 +2668,7 @@ static void
read_products (void *cls,
const char *section)
{
+ const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
struct Product tmpProduct;
char *tmpKey;
char *thumbnail_fn;
@@ -2620,7 +2680,7 @@ read_products (void *cls,
return;
/* the current section is a product, parse its specifications and store it in a temporary product */
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cls,
+ GNUNET_CONFIGURATION_get_value_string (cfg,
section,
"description",
&tmpProduct.description))
@@ -2635,15 +2695,15 @@ read_products (void *cls,
if (0 == strcmp (tmpProduct.description,
"empty"))
{
- tmpProduct.sold_out = GNUNET_YES;
+ tmpProduct.sold_out = true;
}
else
{
- tmpProduct.sold_out = GNUNET_NO;
+ tmpProduct.sold_out = false;
}
}
if (GNUNET_OK !=
- TALER_config_get_amount (cls,
+ TALER_config_get_amount (cfg,
section,
"price",
&tmpProduct.price))
@@ -2654,18 +2714,8 @@ read_products (void *cls,
GNUNET_free (tmpProduct.description);
return;
}
- if (0 != strcasecmp (currency,
- tmpProduct.price.currency))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section,
- "price",
- "currency mismatch");
- GNUNET_free (tmpProduct.description);
- return;
- }
if (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_string (cls,
+ GNUNET_CONFIGURATION_get_value_string (cfg,
section,
"key",
&tmpKey))
@@ -2679,14 +2729,14 @@ read_products (void *cls,
tmpProduct.key = '\0';
}
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cls,
+ GNUNET_CONFIGURATION_get_value_string (cfg,
section,
"instance",
&tmpProduct.instance))
tmpProduct.instance = NULL;
tmpProduct.preview = NULL;
if (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_string (cls,
+ GNUNET_CONFIGURATION_get_value_string (cfg,
section,
"thumbnail",
&thumbnail_fn))
@@ -2778,7 +2828,7 @@ read_products (void *cls,
GNUNET_free (thumbnail_fn);
}
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cls,
+ GNUNET_CONFIGURATION_get_value_number (cfg,
section,
"number",
&tmpProduct.number))
@@ -2791,6 +2841,35 @@ read_products (void *cls,
GNUNET_free (tmpProduct.preview);
return;
}
+
+ {
+ char *auth;
+
+ if ( (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ section,
+ "BACKEND-AUTHORIZATION",
+ &auth)) &&
+ (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ "taler-mdb",
+ "BACKEND-AUTHORIZATION",
+ &auth)) )
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ section,
+ "BACKEND-AUTHORIZATION");
+ GNUNET_free (tmpProduct.description);
+ GNUNET_free (tmpProduct.instance);
+ GNUNET_free (tmpProduct.preview);
+ return;
+ }
+ GNUNET_asprintf (&tmpProduct.auth_header,
+ "%s: %s",
+ MHD_HTTP_HEADER_AUTHORIZATION,
+ auth);
+ GNUNET_free (auth);
+ }
/* append the temporary product to the existing products */
GNUNET_array_append (products,
products_length,
@@ -2800,8 +2879,10 @@ read_products (void *cls,
/**
* @brief Initialise the uart device to send mdb commands
+ *
+ * @return #GNUNET_OK on success
*/
-static int
+static enum GNUNET_GenericReturnValue
mdb_init ()
{
struct termios uart_opts_raw;
@@ -2823,7 +2904,8 @@ mdb_init ()
return GNUNET_SYSERR;
}
- if (0 != tcgetattr (mdb.uartfd, &mdb.uart_opts_backup))
+ if (0 != tcgetattr (mdb.uartfd,
+ &mdb.uart_opts_backup))
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"tcgetattr");
@@ -2886,14 +2968,6 @@ run (void *cls,
(void) args;
(void) cfgfile;
- /* parse the configuration file */
- if (GNUNET_OK !=
- TALER_config_get_currency (cfg,
- &currency))
- {
- global_ret = EXIT_FAILURE;
- return;
- }
/* parse the devices, if no config entry is found, a standard is used */
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (cfg,
@@ -2943,28 +3017,6 @@ run (void *cls,
return;
}
{
- char *auth;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "taler-mdb",
- "backend-authorization",
- &auth))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "taler-mdb",
- "backend-authorization");
- global_ret = EXIT_FAILURE;
- return;
- }
- /* concat the authorization e.g. Authorization: ApiKey sandbox */
- GNUNET_asprintf (&authorization,
- "%s: %s",
- MHD_HTTP_HEADER_AUTHORIZATION,
- auth);
- GNUNET_free (auth);
- }
- {
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"taler-mdb",
@@ -2992,7 +3044,13 @@ run (void *cls,
GNUNET_CONFIGURATION_iterate_sections (cfg,
&read_products,
(void *) cfg);
- GNUNET_assert (NULL != products);
+ if (NULL == products)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No valid products configured\n");
+ global_ret = EXIT_NOTCONFIGURED;
+ return;
+ }
GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
NULL);
@@ -3011,22 +3069,13 @@ run (void *cls,
nfc_init (&context);
if (NULL == context)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unable to initialize NFC (nfc_init() failed)\n");
global_ret = EXIT_FAILURE;
GNUNET_SCHEDULER_shutdown ();
return;
}
- /* initialize HTTP client */
- ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
- &rc);
- rc = GNUNET_CURL_gnunet_rc_create (ctx);
- /* setup authorization */
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CURL_append_header (ctx,
- authorization));
-
/* open gpio pin for cancel button */
{
int efd;
@@ -3035,20 +3084,31 @@ run (void *cls,
O_WRONLY);
if (-1 == efd)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unable to open /gpio/export for cancel button\n");
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
+ have_gpio = false;
+ }
+ else
+ {
+ if (2 != write (efd,
+ "23",
+ 2))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "write",
+ "/sys/class/gpio/export");
+ have_gpio = false;
+ }
+ else
+ {
+ have_gpio = true;
+ }
+ GNUNET_assert (0 == close (efd));
}
- if (2 != write (efd, "23", 2))
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "write",
- "/sys/class/gpio/export");
- GNUNET_assert (0 == close (efd));
}
/* set direction: input */
+ if (have_gpio)
{
int dfd;
@@ -3056,29 +3116,40 @@ run (void *cls,
O_WRONLY);
if (-1 == dfd)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unable to open /gpio/gpio23/direction for cancel button\n");
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
+ have_gpio = false;
+ }
+ else
+ {
+ if (2 != write (dfd,
+ "in",
+ 2))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "write",
+ "/sys/class/gpio/gpio23/direction");
+ have_gpio = false;
+ }
}
- if (2 != write (dfd, "in", 2))
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "write",
- "/sys/class/gpio/gpio23/direction");
GNUNET_assert (0 == close (dfd));
}
- /* actually open fd for reading the state */
- cancel_button.cancelbuttonfd = open ("/sys/class/gpio/gpio23/value",
- O_RDONLY);
- if (-1 == cancel_button.cancelbuttonfd)
+ if (have_gpio)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unable to open /gpio/gpio23/value for cancel button\n");
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
+ /* actually open fd for reading the state */
+ cancel_button.cancelbuttonfd = open ("/sys/class/gpio/gpio23/value",
+ O_RDONLY);
+ if (-1 == cancel_button.cancelbuttonfd)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Unable to open /gpio/gpio23/value for cancel button\n");
+ have_gpio = false;
+ }
+ }
+ else
+ {
+ cancel_button.cancelbuttonfd = -1;
}
@@ -3121,11 +3192,11 @@ run (void *cls,
}
/* get pointer onto frame buffer */
- qrDisplay.memory = mmap (NULL,
- qrDisplay.fix_info.smem_len,
- PROT_READ | PROT_WRITE, MAP_SHARED,
- qrDisplay.devicefd,
- 0);
+ qrDisplay.memory = mmap (NULL,
+ qrDisplay.fix_info.smem_len,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ qrDisplay.devicefd,
+ 0);
if (MAP_FAILED == qrDisplay.memory)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,