gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taler-mdb] branch master updated: delete autosave


From: gnunet
Subject: [taler-taler-mdb] branch master updated: delete autosave
Date: Tue, 10 Dec 2019 15:00:03 +0100

This is an automated email from the git hooks/post-receive script.

marco-boss pushed a commit to branch master
in repository taler-mdb.

The following commit(s) were added to refs/heads/master by this push:
     new e70905e  delete autosave
e70905e is described below

commit e70905eea22e5bd5dd21607d73eeaaf3547aa677
Author: Boss Marco <address@hidden>
AuthorDate: Tue Dec 10 14:59:57 2019 +0100

    delete autosave
---
 src/main.c.autosave | 2599 ---------------------------------------------------
 1 file changed, 2599 deletions(-)

diff --git a/src/main.c.autosave b/src/main.c.autosave
deleted file mode 100644
index 20487f5..0000000
--- a/src/main.c.autosave
+++ /dev/null
@@ -1,2599 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2019 GNUnet e.V.
-
- 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/>
-*/
-/**
-* @file main.c
-* @brief main functionality of the application
-* @author Boss Marco
-* @author Christian Grothoff
-* @author Dominik Hofer
-*
-* TODO:
-* - comment code (Boss)
-*/
-#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#if HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
-#if HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-#include <netinet/ip.h>         /* superset of previous */
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <termios.h>
-#include <nfc/nfc.h>
-#include <microhttpd.h>
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <taler/taler_json_lib.h>
-#include <taler/taler_merchant_service.h>
-#if HAVE_QRENCODE_H
-#include <qrencode.h>
-#endif
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-/* for adafruit pitft display */
-#include <linux/fb.h>
-
-/* Constants */
-#define MAX_SIZE_RX_BUFFER 256
-
-/* Constants */
-#define MAX_SIZE_TX_BUFFER 256
-
-/**
- * Disable i18n support.
- */
-#define _(s) (s)
-
-#define BACKEND_POLL_TIMEOUT GNUNET_TIME_UNIT_MINUTES
-
-#define NFC_FAILURE_RETRY_FREQ GNUNET_TIME_UNIT_SECONDS
-
-/**
- * How long do we wait at most for an ACK from MDB?
- */
-#define MAX_ACK_LATENCY GNUNET_TIME_UNIT_SECONDS
-
-/**
- * Timeout in milliseconds for libnfc operations.
- */
-#define NFC_TIMEOUT 500
-
-#define MAX_HTTP_RETRY_FREQ GNUNET_TIME_relative_multiply ( \
-    GNUNET_TIME_UNIT_MILLISECONDS, 500)
-
-#define MAX_HTTP_RETRY_FREQ GNUNET_TIME_relative_multiply ( \
-    GNUNET_TIME_UNIT_MILLISECONDS, 500)
-
-/**
- * How long could it take at most for us to notify the Taler merchant
- * backend to grant a refund to a user if dispensing the product
- * failed? (Very conservative value here, for vending machines brewing
- * coffee or something complex that could fail.)
- */
-#define MAX_REFUND_DELAY GNUNET_TIME_relative_multiply ( \
-    GNUNET_TIME_UNIT_MINUTES, 5)
-
-/**
- * Code returned by libnfc in case of success.
- */
-#define APDU_SUCCESS "\x90\x00"
-
-/**
- * Code returned by libnfc in case Taler wallet is not installed.
- */
-#define APDU_NOT_FOUND "\x6a\x82"
-
-/* upper and lower bounds for mifare targets uid length */
-/**
-  * Upper lenght of the uid for a valid MIFARE target
-  */
-#define UID_LEN_UPPER 7
-
-/**
-  * Lower lenght of the uid for a valid MIFARE target
-  */
-#define UID_LEN_LOWER 4
-
-/* Commands for communication via MDB/ICP */
-/* VMC commands */
-#define VMC_CMD_START 0x02
-#define VMC_CMD_END 0x03
-
-/**
- * Acknowledgement
- */
-#define VMC_ACKN 0x00
-
-/**
- * Request for configuration.
- */
-#define VMC_CONF 0x11
-
-/**
- * Machine is polling for something.
- */
-#define VMC_POLL 0x12
-
-/**
- * Vending, with sub-command.
- */
-#define VMC_VEND 0x13
-#define VMC_VEND_REQUEST 0x00
-#define VMC_VEND_CANCEL 0x01
-#define VMC_VEND_SUCCESS 0x02
-#define VMC_VEND_FAILURE 0x03
-#define VMC_VEND_SESSION_COMPLETE 0x04
-
-/**
- * Commands for the reader (our device).
- */
-#define VMC_READER 0x14
-#define VMC_READER_DISABLE 0x00
-#define VMC_READER_ENABLE 0x01
-#define VMC_READER_CANCEL 0x02
-
-#define VMC_REQUEST_ID 0x17
-
-/**
- * Out of sequence.
- */
-#define VMC_OOSQ 0xB0
-
-/**
- * Request to retransmit last command.
- */
-#define VMC_RETR 0xAA
-
-/* Reader commands */
-
-/* Config Data */
-/* Refer to the mdb interface specifications v4.2 p.288 */
-#define READER_CONFIG "01"
-#define READER_FEATURE_LEVEL "01"
-#define READER_COUNTRYCODE "1978"
-#define READER_SCALE_FACTOR "0A"
-#define READER_DECIMAL_PLACES "02"
-#define READER_MAX_RESPONSE_TIME "FF"
-#define READER_MISC_OPTIONS "0C"
-
-/* Session Commands */
-/* Refer to the mdb interface specifications v4.2 p.131 */
-#define READER_BEGIN_SESSION "03"
-#define READER_FUNDS_AVAILABLE "FFFF"
-#define READER_END_SESSION "07"
-
-/* Vend Commands */
-/* Refer to the mdb interface specifications v4.2 p.134 */
-#define READER_VEND_APPROVE "05"
-#define READER_VEND_AMOUNT "0001"
-#define READER_VEND_DENIED "06"
-
-/* Cancelled Command */
-#define READER_CANCELLED "08"
-
-/* Unused reader commands */
-#define READER_DISPLAY_REQUEST "02"
-#define READER_SESSION_CANCEL_REQUEST "04"
-#define READER_REVALUE_APPROVED "0D"
-#define READER_REVALUE_DENIED "0E"
-
-/**
- * Datatype for mdb subcommands and data
- */
-struct MdbBlock
-{
-  uint8_t *bin;
-
-  size_t bin_size;
-};
-
-
-/**
- * Datatype for mdb command
- */
-struct MdbCommand
-{
-  const char *name;
-
-  struct MdbBlock cmd;
-
-  struct MdbBlock data;
-};
-
-
-/**
- * Struct holding the information for a product to sell
- */
-struct Product
-{
-  /**
-   * The price for the product
-   */
-  struct TALER_Amount price;
-
-  /**
-   * Description (or name) of the product
-   */
-  char *description;
-
-  /**
-   * Number of the product in the vending machine
-   */
-  unsigned long long number;
-
-  /**
-   * Key for the product (optional, needed to test the application without 
vending machine)
-   */
-  char key;
-};
-
-
-/**
- * Handle for a payment
- */
-struct PaymentActivity
-{
-  /**
-   * Handle to a PUT /proposal operation
-   */
-  struct TALER_MERCHANT_ProposalOperation *po;
-
-  /**
-   * Handle for a /check-payment operation.
-   */
-  struct TALER_MERCHANT_CheckPaymentOperation *cpo;
-
-  /**
-   * Order ID for pending order
-   */
-  char *order_id;
-
-  /**
-   * URI needed to pay the pending order
-   */
-  char *taler_pay_uri;
-
-  /**
-   * NFC device
-   */
-  nfc_device *pnd;
-
-  /**
-   * Target to send the data via NFC
-   */
-  nfc_target nt;
-
-  /**
-   * Current task running
-   */
-  struct GNUNET_SCHEDULER_Task *task;
-
-  /**
-   * Tasks delayed
-   */
-  struct GNUNET_SCHEDULER_Task *delay_task;
-
-  /**
-   * Payment checking delayed task
-   */
-  struct GNUNET_SCHEDULER_Task *delay_pay_task;
-
-  /**
-   * What is the price the user is paying?
-   */
-  struct TALER_Amount amount;
-
-  /**
-   * Member to see if the wallet already received a uri
-   * GNUNET_YES, GNUNET_NO
-   * If yes, tunneling can be offered to the wallet
-   */
-  int wallet_has_uri;
-
-  /**
-   * Set to #GNUNET_YES once the product has been paid
-   * (and we are in the process of yielding the product).
-   */
-  int paid;
-};
-
-
-/**
- * Data structures associated with the MDB.
- */
-struct MdbHandle
-{
-
-  uint8_t rxBuffer[MAX_SIZE_RX_BUFFER];
-
-  uint8_t txBuffer[MAX_SIZE_TX_BUFFER];
-
-  struct GNUNET_SCHEDULER_Task *rtask;
-
-  struct GNUNET_SCHEDULER_Task *wtask;
-
-  const struct MdbCommand *cmd;
-
-  const struct MdbCommand *last_cmd;
-
-  size_t rx_off;
-
-  /**
-   * Current write offset in @e txBuffer.
-   */
-  size_t tx_off;
-
-  /**
-   * Number of bytes in @e txBuffer with the serialized data of the
-   * @e last_cmd.
-   */
-  size_t tx_len;
-
-  struct GNUNET_TIME_Absolute ack_timeout;
-
-  struct termios uart_opts_backup;
-
-  int session_running;
-
-  int uartfd;
-
-};
-
-
-/**
- * Handle for the Framebuffer device
- */
-struct Display
-{
-  /**
-   * File descriptor for the screen
-   */
-  int devicefd;
-
-  /**
-   * File descriptor to set backlight information
-   */
-  int backlightfd;
-
-  /**
-   * The display memory to set the pixel information
-   */
-  uint16_t *memory;
-
-  /**
-   * Original screen information
-   */
-  struct fb_var_screeninfo orig_vinfo;
-
-  /**
-   * Variable screen information (color depth ...)
-   */
-  struct fb_var_screeninfo var_info;
-
-  /**
-   * Fixed screen informtaion
-   */
-  struct fb_fix_screeninfo fix_info;
-};
-
-
-/**
- * DLL of pending refund operations.
- */
-struct Refund
-{
-  /**
-   * DLL next pointer.
-   */
-  struct Refund *next;
-
-  /**
-   * DLL prev pointer.
-   */
-  struct Refund *prev;
-
-  /**
-   * Handle to the ongoing operation.
-   */
-  struct TALER_MERCHANT_RefundIncreaseOperation *rio;
-
-};
-
-
-/**
- * DLL head of refunds.
- */
-static struct Refund *refund_head;
-
-/**
- * DLL tail of refunds.
- */
-static struct Refund *refund_tail;
-
-/**
- * NFC context used by the NFC reader
- */
-static nfc_context *context;
-
-/**
- * Global return value
- */
-static int global_ret;
-
-/**
- * Flag set to remember that we are in shutdown.
- */
-static int in_shutdown;
-
-/**
- * Refenence to the keyboard task
- */
-static struct GNUNET_SCHEDULER_Task *keyboard_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 *backendBaseUrl;
-
-/**
- * Taler fulfillment url read from configuration file
- */
-static char *fulfillmentUrl;
-
-/**
- * Fulfillment message to display after successfull payment, read from 
configuration file
- */
-static char *fulfillmentMsg;
-
-/**
- * Authorization for the taler backend
- */
-static char *authorization;
-
-/**
- * Handle for the payment
- */
-static struct PaymentActivity *payment_activity;
-
-/**
- * Products read from configuration file
- */
-static struct Product *products;
-
-/**
- * Amount of products
- */
-static unsigned int products_length;
-
-/**
- * Data associated with the MDB session.
- */
-static struct MdbHandle mdb;
-
-/**
- * MDB response to the request for configuration.
- */
-static struct MdbCommand readerConfigData;
-
-/**
- * Ask MDB to begin session (with "infinite" money)
- */
-static struct MdbCommand beginSession;
-
-/**
- * Refuse vending request (payment failed)
- */
-static struct MdbCommand denyVend;
-
-/**
- * Approve vending request (payment succeeded)
- */
-static struct MdbCommand approveVend;
-
-/**
- * Confirm cancellation by machine.
- */
-static struct MdbCommand readerCancelled;
-
-/**
- * Terminate session.
- */
-static struct MdbCommand endSession;
-
-/**
- * Name of the framebuffer device (i.e. /dev/fb1).
- */
-static char *framebuffer_device_filename;
-
-/**
- * Name of the backlight file of @e framebuffer_device_filename (i.e. 
/sys/class/backlight/soc:backlight/brightness).
- */
-static char *framebuffer_backlight_filename;
-
-/**
- * Global option '-i' to invert backlight on/off values
- */
-static int backlight_invert;
-
-/**
- * Standard backlight on value
- */
-static char backlight_on = '1';
-
-/**
- * Standard backlight off value
- */
-static char backlight_off = '0';
-
-/**
- * Name of the UART device with the MDB (i.e. /dev/ttyAMA0).
- */
-static char *uart_device_filename;
-
-/**
- * Global option '-d' to disable MDB set.
- */
-static int disable_mdb;
-
-/**
- * Global option '-t' to disable stdin / terminal.
- */
-static int disable_tty;
-
-/**
- * Taler wallet application identifier
- */
-static const uint8_t taler_aid[] = { 0xF0, 0x00, 0x54, 0x41, 0x4c, 0x45, 0x52 
};
-
-/**
- * NFC select file command to select wallet aid
- */
-static const uint8_t select_file[] = { 0x00, 0xA4, 0x04, 0x00, 0x07 };
-
-/**
- * NFC put command to send data to the wallet
- */
-static const uint8_t put_data[] = { 0x00, 0xDA, 0x01, 0x00, 0x7c, 0x01 };
-
-#if FUTURE_FEATURES
-/* tunneling */
-static const uint8_t get_data[] = { 0x00, 0xCA, 0x01, 0x00, 0x00, 0x00 };
-#endif
-
-/**
- * Handle for the framebuffer device
- */
-static struct Display qrDisplay;
-
-
-#if HAVE_QRENCODE_H
-#include <qrencode.h>
-
-/**
- * @brief Create the QR code to pay and display it on screen
- *
- * @param uri what text to show in the QR code
- */
-static void
-show_qrcode (const char *uri)
-{
-  QRinput *qri;
-  QRcode *qrc;
-  unsigned int size;
-  char *upper;
-  char *base;
-  size_t xOff;
-  size_t yOff;
-  const char *dddash;
-
-  if (0 > qrDisplay.devicefd)
-    return; /* no display, no dice */
-  /* find the fourth '/' in the payto://pay/hostname/-uri */
-  dddash = strchr (uri, '/');
-  if (NULL != dddash)
-    dddash = strchr (dddash + 1, '/');
-  if (NULL != dddash)
-    dddash = strchr (dddash + 1, '/');
-  if (NULL != dddash)
-    dddash = strchr (dddash + 1, '/');
-  if (NULL == dddash)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "taler://pay/-URI malformed: `%s'\n",
-                uri);
-    return;
-  }
-
-  qri = QRinput_new2 (0, QR_ECLEVEL_L);
-  if (NULL == qri)
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                         "QRinput_new2");
-    return;
-  }
-#if UPPER_SUPPORTED
-  /* convert all characters until the fourth '/' to upper
-     case. The rest _should_ be upper case in a NICE setup,
-     but we can't warrant it and must not touch those. */
-  base = GNUNET_strndup (uri,
-                         dddash - uri);
-
-  GNUNET_STRINGS_utf8_toupper (base, base);
-  GNUNET_asprintf (&upper,
-                   "%s%s",
-                   base,
-                   dddash);
-  GNUNET_free (base);
-#else
-  (void) dddash;
-  upper = GNUNET_strdup (uri);
-#endif
-  /* first try encoding as uppercase-only alpha-numerical
-     QR code (much smaller encoding); if that fails, also
-     try using binary encoding (in case nick contains
-     special characters). */
-  if ( (0 !=
-        QRinput_append (qri,
-                        QR_MODE_AN,
-                        strlen (upper),
-                        (unsigned char *) upper)) &&
-       (0 !=
-        QRinput_append (qri,
-                        QR_MODE_8,
-                        strlen (upper),
-                        (unsigned char *) upper)))
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                         "QRinput_append");
-    GNUNET_free (upper);
-    return;
-  }
-  GNUNET_free (upper);
-  qrc = QRcode_encodeInput (qri);
-  if (NULL == qrc)
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                         "QRcode_encodeInput");
-    QRinput_free (qri);
-    return;
-  }
-
-  /* +8 for 4-pixels border */
-  size = GNUNET_MIN (qrDisplay.var_info.xres,
-                     qrDisplay.var_info.yres);
-  unsigned int nwidth = qrc->width + 8; /* 4 pixel border */
-  xOff = 4 * size / nwidth;
-  yOff = 4 * size / nwidth;
-  if (qrDisplay.var_info.xres < qrDisplay.var_info.yres)
-    yOff += (qrDisplay.var_info.yres - qrDisplay.var_info.xres) / 2;
-  else
-    xOff += (qrDisplay.var_info.xres - qrDisplay.var_info.yres) / 2;
-  for (unsigned int x = 0; x < qrDisplay.var_info.xres - 2 * xOff; x++)
-    for (unsigned int y = 0; y < qrDisplay.var_info.yres - 2 * yOff; y++)
-    {
-      unsigned int xoff = x * nwidth / size;
-      unsigned int yoff = y * nwidth / size;
-      unsigned int off = xoff + yoff * qrc->width;
-      if ( (xoff >= (unsigned) qrc->width) ||
-           (yoff >= (unsigned) qrc->width) )
-        continue;
-      qrDisplay.memory[(y + yOff) * qrDisplay.var_info.xres + (x + xOff)] =
-        (0 == (qrc->data[off] & 1)) ? 0xFFFF : 0x0000;
-    }
-
-  QRcode_free (qrc);
-  QRinput_free (qri);
-
-  if (0 < qrDisplay.backlightfd)
-    (void) write (qrDisplay.backlightfd, &backlight_on, 1);
-}
-
-
-#endif
-
-
-static void
-run_mdb_event_loop (void);
-
-
-/**
- * @brief Cleanup all the data when a order has succeeded or got cancelled
- * @param pa the payment activity to clean up
- */
-static void
-cleanup_payment (struct PaymentActivity *pa)
-{
-  if (NULL != pa->pnd)
-  {
-    nfc_abort_command (pa->pnd);
-    nfc_close (pa->pnd);
-  }
-  if (NULL != pa->po)
-    TALER_MERCHANT_proposal_cancel (pa->po);
-  if (NULL != pa->cpo)
-    TALER_MERCHANT_check_payment_cancel (pa->cpo);
-  GNUNET_CURL_gnunet_scheduler_reschedule (&rc);
-  if (NULL != pa->task)
-    GNUNET_SCHEDULER_cancel (pa->task);
-  if (NULL != pa->delay_task)
-    GNUNET_SCHEDULER_cancel (pa->delay_task);
-  if (NULL != pa->delay_pay_task)
-    GNUNET_SCHEDULER_cancel (pa->delay_pay_task);
-  if (NULL != pa->taler_pay_uri)
-  {
-#if HAVE_QRENCODE_H
-    if (NULL != qrDisplay.memory)
-      memset (qrDisplay.memory,
-              0xFF,
-              qrDisplay.var_info.xres * qrDisplay.var_info.yres
-              * sizeof (uint16_t));
-    if (0 < qrDisplay.backlightfd)
-      (void) write (qrDisplay.backlightfd, &backlight_off, 1);
-#endif
-    GNUNET_free (pa->taler_pay_uri);
-  }
-  GNUNET_free_non_null (pa->order_id);
-  GNUNET_free (pa);
-}
-
-
-/**
- * @brief Shutdown the mdb communication tasks
- */
-static void
-mdb_shutdown ()
-{
-  if (NULL != mdb.rtask)
-  {
-    GNUNET_SCHEDULER_cancel (mdb.rtask);
-    mdb.rtask = NULL;
-  }
-  if (NULL != mdb.wtask)
-  {
-    GNUNET_SCHEDULER_cancel (mdb.wtask);
-    mdb.wtask = NULL;
-  }
-  if (disable_mdb)
-    return;
-  /* restore UART */
-  if (0 != tcsetattr (mdb.uartfd,
-                      TCSAFLUSH,
-                      &mdb.uart_opts_backup))
-  {
-    printf ("Failed to restore uart discipline\n");
-    global_ret = EXIT_FAILURE;
-  }
-  if (-1 != mdb.uartfd)
-  {
-    (void) close (mdb.uartfd);
-    mdb.uartfd = -1;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Shutdown complete (including MDB)\n");
-}
-
-
-/**
- * @brief Shutdown the application.
- *
- * @param cls closure
- */
-static void
-shutdown_task (void *cls)
-{
-  struct Refund *r;
-
-  (void) cls;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Shutdown initiated\n");
-  while (NULL != (r = refund_head))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Pending refund operation aborted due to shutdown\n");
-    GNUNET_CONTAINER_DLL_remove (refund_head,
-                                 refund_tail,
-                                 r);
-    TALER_MERCHANT_refund_increase_cancel (r->rio);
-    GNUNET_free (r);
-  }
-  if (NULL != context)
-  {
-    nfc_exit (context);
-    context = NULL;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "NFC down\n");
-  if (NULL != payment_activity)
-  {
-    cleanup_payment (payment_activity);
-    payment_activity = NULL;
-  }
-  if (NULL != keyboard_task)
-  {
-    GNUNET_SCHEDULER_cancel (keyboard_task);
-    keyboard_task = NULL;
-  }
-  /* 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 (NULL != qrDisplay.memory)
-  {
-    /* free the display data  */
-    munmap (qrDisplay.memory,
-            qrDisplay.fix_info.smem_len);
-    qrDisplay.memory = NULL;
-    /* reset original state */
-    if (0 > ioctl (qrDisplay.devicefd,
-                   FBIOPUT_VSCREENINFO,
-                   &qrDisplay.orig_vinfo))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  "failed to reset originial display state\n");
-    }
-    /* close device */
-    close (qrDisplay.devicefd);
-    qrDisplay.devicefd = -1;
-    if (0 < qrDisplay.backlightfd)
-      close (qrDisplay.backlightfd);
-    qrDisplay.backlightfd = -1;
-  }
-  if (NULL != products)
-  {
-    for (unsigned int i = 0; i < products_length; i++)
-      GNUNET_free (products[i].description);
-    GNUNET_array_grow (products,
-                       products_length,
-                       0);
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Shutdown complete (except for MDB)\n");
-}
-
-
-static void
-check_payment_again (void *cls);
-
-
-static void
-connect_target (void *cls);
-
-
-static void
-wallet_select_aid (void *cls);
-
-
-/**
- * @brief Transmit the pay uri from taler to the wallet application via NFC
- *
- * @param cls closure
- */
-static void
-wallet_transmit_uri (void *cls)
-{
-  struct PaymentActivity *pa = cls;
-  uint8_t response[] = { 0x00, 0x00 };
-  size_t slen = strlen (pa->taler_pay_uri);
-  uint8_t message[sizeof (put_data) + slen];
-
-  pa->delay_task = NULL;
-  memcpy (message, put_data, sizeof (put_data));
-  memcpy (&message[sizeof (put_data)], pa->taler_pay_uri, slen);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Sending 'PUT DATA' command for `%s' to wallet\n",
-              pa->taler_pay_uri);
-  if (0 > nfc_initiator_transceive_bytes (pa->pnd,
-                                          message,
-                                          sizeof (message),
-                                          response,
-                                          sizeof(response),
-                                          NFC_TIMEOUT))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Failed to send command via NFC\n");
-    pa->task = GNUNET_SCHEDULER_add_now (&connect_target,
-                                         pa);
-    return;
-  }
-  if (0 != memcmp (response,
-                   APDU_SUCCESS,
-                   sizeof (response)))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "'PUT DATA' command transmission failed, return code: %x%x\n",
-                response[0],
-                response[1]);
-    pa->task = GNUNET_SCHEDULER_add_now (&connect_target,
-                                         pa);
-    return;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "'PUT DATA' command sent successfully via NFC\n");
-  pa->wallet_has_uri = GNUNET_YES;
-  /* FIXME: or just offer Internet service here? */
-  pa->delay_task = GNUNET_SCHEDULER_add_delayed (MAX_HTTP_RETRY_FREQ,
-                                                 &wallet_transmit_uri,
-                                                 pa);
-}
-
-
-/**
- * @brief Select the taler wallet app via NFC
- *
- * @param cls closure
- */
-static void
-wallet_select_aid (void *cls)
-{
-  struct PaymentActivity *pa = cls;
-  uint8_t response[] = { 0x00, 0x00 };
-  uint8_t message[sizeof(select_file) + sizeof(taler_aid)];
-
-  pa->task = NULL;
-  memcpy (message, select_file, sizeof (select_file));
-  memcpy (&message[sizeof (select_file)], taler_aid, sizeof (taler_aid));
-
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Trying to find Taler wallet on NFC\n");
-  if (0 > nfc_initiator_transceive_bytes (pa->pnd,
-                                          message,
-                                          sizeof (message),
-                                          response,
-                                          sizeof (response),
-                                          NFC_TIMEOUT))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Failed to transceive with NFC app, trying to find another NFC 
client\n");
-    pa->task = GNUNET_SCHEDULER_add_now (&connect_target,
-                                         pa);
-    return;
-  }
-  if (0 == memcmp (response,
-                   APDU_SUCCESS,
-                   sizeof (response)))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Taler wallet found over NFC\n");
-    pa->delay_task = GNUNET_SCHEDULER_add_now (&wallet_transmit_uri,
-                                               pa);
-    return;
-  }
-  if (0 == memcmp (response,
-                   APDU_NOT_FOUND,
-                   sizeof (response)))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Taler wallet NOT found on this device\n");
-    pa->task = GNUNET_SCHEDULER_add_now (&connect_target,
-                                         pa);
-    return;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-              "AID selection failure, return code: %x%x, trying to find 
another NFC client\n",
-              response[0],
-              response[1]);
-  pa->task = GNUNET_SCHEDULER_add_delayed (NFC_FAILURE_RETRY_FREQ,
-                                           &connect_target,
-                                           pa);
-}
-
-
-/**
- * @brief Connect the NFC reader with a compatible NFC target
- *
- * @param cls closure
- */
-static void
-connect_target (void *cls)
-{
-  struct PaymentActivity *pa = cls;
-  const nfc_modulation nmMifare = {
-    .nmt = NMT_ISO14443A,
-    .nbr = NBR_212,
-  };
-
-  pa->task = NULL;
-  pa->nt.nti.nai.szUidLen = 0;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Trying to find NFC client\n");
-  if (0 > nfc_initiator_poll_target (pa->pnd,
-                                     &nmMifare,
-                                     1,
-                                     0x01,
-                                     0x01,
-                                     &pa->nt))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Failed to connect to NFC target\n");
-  }
-  else if ( (pa->nt.nti.nai.szUidLen > UID_LEN_UPPER) ||
-            (pa->nt.nti.nai.szUidLen < UID_LEN_LOWER) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to connect, wrong NFC modulation\n");
-  }
-  else
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Found NFC client\n");
-    pa->task = GNUNET_SCHEDULER_add_now (&wallet_select_aid,
-                                         pa);
-    return;
-  }
-  pa->task = GNUNET_SCHEDULER_add_delayed (NFC_FAILURE_RETRY_FREQ,
-                                           &connect_target,
-                                           pa);
-}
-
-
-/**
- * @brief Open the NFC reader.
- *
- * @param cls closure
- */
-static void
-open_nfc_reader (void *cls)
-{
-  struct PaymentActivity *pa = cls;
-
-  pa->task = NULL;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Trying to open NFC device\n");
-  pa->pnd = nfc_open (context, NULL);
-  if (NULL == pa->pnd)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Payment inititation: Unable to open NFC device\n");
-    pa->task = GNUNET_SCHEDULER_add_delayed (NFC_FAILURE_RETRY_FREQ,
-                                             &open_nfc_reader,
-                                             pa);
-    return;
-  }
-  if (0 > nfc_initiator_init (pa->pnd))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to initialize NFC device: %s\n",
-                nfc_strerror (pa->pnd));
-    cleanup_payment (pa);
-    GNUNET_assert (payment_activity == pa);
-    payment_activity = NULL;
-    return;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "NFC in operation %s / %s\n",
-              nfc_device_get_name (pa->pnd),
-              nfc_device_get_connstring (pa->pnd));
-  pa->task = GNUNET_SCHEDULER_add_now (&connect_target,
-                                       pa);
-}
-
-
-static void
-start_read_keyboard (void);
-
-
-/**
- * @brief Callback to process a GET /check-payment request
- *
- * @param cls closure
- * @param http_status HTTP status code for this request
- * @param obj raw response body
- * @param paid #GNUNET_YES if the payment is settled, #GNUNET_NO if not
- *        settled, #GNUNET_SYSERR on error
- *        (note that refunded payments are returned as paid!)
- * @param refunded #GNUNET_YES if there is at least on refund on this payment,
- *        #GNUNET_NO if refunded, #GNUNET_SYSERR or error
- * @param refunded_amount amount that was refunded, NULL if there
- *        was no refund
- * @param taler_pay_uri the URI that instructs the wallets to process
- *                      the payment
- */
-static void
-check_payment_cb (void *cls,
-                  unsigned int http_status,
-                  const json_t *obj,
-                  int paid,
-                  int refunded,
-                  struct TALER_Amount *refund_amount,
-                  const char *taler_pay_uri)
-{
-  struct PaymentActivity *pa = cls;
-
-  (void) refunded;
-  (void) refund_amount;
-  (void) obj;
-  GNUNET_assert (payment_activity == pa);
-  pa->cpo = NULL;
-  if (MHD_HTTP_OK != http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Backend request to /check-payment failed: %u\n",
-                http_status);
-    mdb.cmd = &denyVend;
-    run_mdb_event_loop ();
-    cleanup_payment (pa);
-    GNUNET_assert (payment_activity == pa);
-    payment_activity = NULL;
-    return;
-  }
-
-  if (paid)
-  {
-    mdb.cmd = &approveVend;
-    payment_activity->paid = GNUNET_YES;
-    run_mdb_event_loop ();
-    if ((disable_mdb) && (! disable_tty))
-    {
-      GNUNET_SCHEDULER_cancel (keyboard_task);
-      keyboard_task = NULL;
-      start_read_keyboard ();
-    }
-    return;
-  }
-  else
-  {
-    /* Start to check for payment. Note that we do this even before
-       we talked successfully to the wallet via NFC because we MAY show the
-       QR code in the future and in that case the payment may happen
-       anytime even before the NFC communication succeeds. */
-    if ( (NULL == pa->cpo) &&
-         (NULL == pa->delay_pay_task) )
-    {
-      pa->delay_pay_task = GNUNET_SCHEDULER_add_delayed (MAX_HTTP_RETRY_FREQ,
-                                                         &check_payment_again,
-                                                         pa);
-    }
-  }
-  if (NULL == pa->taler_pay_uri)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Trying to talk to wallet to give it pay URI `%s'\n",
-                taler_pay_uri);
-    GNUNET_assert (NULL == pa->pnd);
-    pa->taler_pay_uri = GNUNET_strdup (taler_pay_uri);
-#if HAVE_QRENCODE_H
-    show_qrcode (taler_pay_uri);
-#endif
-    pa->task = GNUNET_SCHEDULER_add_now (&open_nfc_reader,
-                                         pa);
-  }
-}
-
-
-/**
- * @brief Check the payment status again
- *
- * @param cls closure
- */
-static void
-check_payment_again (void *cls)
-{
-  struct PaymentActivity *pa = cls;
-
-  pa->delay_pay_task = NULL;
-  GNUNET_assert (NULL == pa->cpo);
-  pa->cpo = TALER_MERCHANT_check_payment (ctx,
-                                          backendBaseUrl,
-                                          pa->order_id,
-                                          NULL /* snack machine, no Web crap 
*/,
-                                          BACKEND_POLL_TIMEOUT,
-                                          &check_payment_cb,
-                                          pa);
-}
-
-
-/**
- * @brief Callback for a PUT /order request
- *
- * @param cls closure
- * @param http_status HTTP status code for this request
- * @param ec Taler error code
- * @param obj raw response body
- * @param order_id order ID of the order created
- */
-static void
-proposal_cb (void *cls,
-             unsigned int http_status,
-             enum TALER_ErrorCode ec,
-             const json_t *obj,
-             const char *order_id)
-{
-  (void) obj;
-  struct PaymentActivity *pa = cls;
-
-  pa->po = NULL;
-  if (MHD_HTTP_OK != http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to setup order with backend: %u/%d\n",
-                http_status,
-                (int) ec);
-    mdb.cmd = &denyVend;
-    run_mdb_event_loop ();
-    cleanup_payment (pa);
-    GNUNET_assert (payment_activity == pa);
-    payment_activity = NULL;
-    return;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Backend successfully created order `%s'\n",
-              order_id);
-  pa->order_id = GNUNET_strdup (order_id);
-  pa->cpo = TALER_MERCHANT_check_payment (ctx,
-                                          backendBaseUrl,
-                                          pa->order_id,
-                                          NULL /* snack machine, no Web crap 
*/,
-                                          GNUNET_TIME_UNIT_ZERO,
-                                          &check_payment_cb,
-                                          pa);
-}
-
-
-/**
- * @brief Launch a new order
- *
- * @param product information for product to sell
- * @return payment activity for the order, NULL on failure
- */
-static struct PaymentActivity *
-launch_payment (const struct Product *product)
-{
-  struct PaymentActivity *pa;
-  json_t *orderReq;
-  char *fulflmntUrl;
-  struct GNUNET_ShortHashCode uuid;
-  char *uuid_s;
-
-  /* We need to ensure that every fulfillment URL is unique;
-     most easily done by adding a random nonce, as we may
-     not have a reliable counter or clock on the machine */
-  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
-                              &uuid,
-                              sizeof (uuid));
-  uuid_s = GNUNET_STRINGS_data_to_string_alloc (&uuid,
-                                                sizeof (uuid));
-  /* create the fulfillment url, e.g. 
"taler://fulfillment-success/Enjoy+your+ice+cream!"; */
-  GNUNET_asprintf (&fulflmntUrl,
-                   "%s%s%s#%s",
-                   fulfillmentUrl,
-                   fulfillmentMsg,
-                   product->description,
-                   uuid_s);
-  GNUNET_free (uuid_s);
-  /* create the json object for the order request */
-  orderReq = json_pack ("{ s:s, s:o, s:s, s:o }",
-                        "summary", product->description,
-                        "amount", TALER_JSON_from_amount (&product->price),
-                        "fulfillment_url", fulflmntUrl
-                        ,"auto_refund", GNUNET_JSON_from_time_rel (
-                          MAX_REFUND_DELAY)
-                        );
-  GNUNET_free (fulflmntUrl);
-  if (NULL == orderReq)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "json_pack failed (out of memory?)\n");
-    return NULL;
-  }
-  pa = GNUNET_new (struct PaymentActivity);
-  pa->amount = product->price;
-  pa->po = TALER_MERCHANT_order_put (ctx,
-                                     backendBaseUrl,
-                                     orderReq,
-                                     &proposal_cb,
-                                     pa);
-  json_decref (orderReq);
-  if (NULL == pa->po)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "TALER_MERCHANT_order_put failed (out of memory?)\n");
-    GNUNET_free (pa);
-    return NULL;
-  }
-  return pa;
-}
-
-
-/**
- * @brief Vending successful, conclude payment activity.
- */
-static void
-vend_success ()
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "MDB vend success received\n");
-  GNUNET_break (NULL != payment_activity);
-  if (NULL != payment_activity)
-  {
-    cleanup_payment (payment_activity);
-    payment_activity = NULL;
-  }
-}
-
-
-/**
- * @brief Callback to process a POST /refund request
- *
- * @param cls closure
- * @param http_status HTTP status code for this request
- * @param ec taler-specific error code
- * @param obj the response body
- */
-static void
-refund_complete_cb (void *cls,
-                    unsigned int http_status,
-                    enum TALER_ErrorCode ec,
-                    const json_t *obj)
-{
-  struct Refund *r = cls;
-
-  r->rio = NULL;
-  if (MHD_HTTP_OK != http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to grant consumer refund: %u/%d\n",
-                http_status,
-                ec);
-  }
-  GNUNET_CONTAINER_DLL_remove (refund_head,
-                               refund_tail,
-                               r);
-  GNUNET_free (r);
-}
-
-
-/**
- * @brief Vending failed, provide refund.
- */
-static void
-vend_failure ()
-{
-  struct Refund *r;
-
-  if (NULL == payment_activity)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Received MDB vend failure, refunding customer\n");
-  mdb.cmd = &endSession;
-  mdb.session_running = GNUNET_NO;
-  r = GNUNET_new (struct Refund);
-  r->rio = TALER_MERCHANT_refund_increase (ctx,
-                                           backendBaseUrl,
-                                           payment_activity->order_id,
-                                           &payment_activity->amount,
-                                           "failed to dispense product",
-                                           &refund_complete_cb,
-                                           r);
-  if (NULL == r->rio)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to launch refund interaction with the merchant 
backend!\n");
-    GNUNET_free (r);
-  }
-  else
-  {
-    GNUNET_CONTAINER_DLL_insert (refund_head,
-                                 refund_tail,
-                                 r);
-  }
-  if (NULL != payment_activity)
-  {
-    cleanup_payment (payment_activity);
-    payment_activity = NULL;
-  }
-}
-
-
-/**
- * @brief Read the character from stdin and activate the selected task
- *
- * @param cls closure
- */
-static void
-read_keyboard_command (void *cls)
-{
-  (void) cls;
-  int input;
-
-  keyboard_task = NULL;
-  input = getchar ();
-  if ( (EOF == input) ||
-       ('x' == (char) input) )
-  {
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-  if (NULL != payment_activity)
-  {
-    switch ((char) input)
-    {
-    case 'c':
-      if (GNUNET_NO == payment_activity->paid)
-      {
-        mdb.cmd = &denyVend;
-      }
-      else
-      {
-        mdb.cmd = &endSession;
-        mdb.session_running = GNUNET_NO;
-      }
-      run_mdb_event_loop ();
-      cleanup_payment (payment_activity);
-      payment_activity = NULL;
-      break;
-    case 'a':
-      payment_activity->paid = GNUNET_YES;
-      mdb.cmd = &approveVend;
-      run_mdb_event_loop ();
-      break;
-    case 'n':
-      if (disable_mdb)
-      {
-        vend_failure ();
-      }
-      else
-      {
-        fprintf (stderr,
-                 "Cannot fail to vend at this time, waiting for payment\n");
-      }
-      break;
-    case 'y':
-      if (disable_mdb)
-      {
-        vend_success ();
-      }
-      else
-      {
-        fprintf (stderr,
-                 "Cannot succeed to vend at this time, waiting for payment\n");
-      }
-      break;
-    default:
-      fprintf (stderr,
-               "Unknown command `%c'\n",
-               input);
-      break;
-    }
-    start_read_keyboard ();
-    return;
-  }
-  if (NULL != payment_activity)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Purchase activity already pending\n");
-    start_read_keyboard ();
-    return;
-  }
-  for (unsigned int i = 0; i < products_length; i++)
-    if (((char) input) == products[i].key)
-    {
-      payment_activity = launch_payment (&products[i]);
-      start_read_keyboard ();
-      return;
-    }
-  fprintf (stderr,
-           "Unknown command '%c'\n",
-           (char) input);
-  start_read_keyboard ();
-}
-
-
-/**
- * @brief Wait for a keyboard input
- */
-static void
-start_read_keyboard ()
-{
-  static struct GNUNET_DISK_FileHandle fh = { STDIN_FILENO };
-
-  GNUNET_assert (NULL == keyboard_task);
-  if (NULL == payment_activity)
-  {
-    for (unsigned int i = 0; i < products_length; i++)
-      printf ("'%c' to buy %s\n",
-              products[i].key,
-              products[i].description);
-  }
-  else
-  {
-    if (GNUNET_NO == payment_activity->paid)
-    {
-      printf ("'a' to fake payment for the last purchase\n"
-              "'c' to cancel last purchase\n");
-    }
-    else
-    {
-      if (disable_mdb)
-        printf ("'y' to simulate product successfully dispensed\n"
-                "'n' to simulate product failed to be dispensed\n");
-    }
-  }
-  printf ("'x' to quit\n");
-  printf ("Waiting for keyboard input\n");
-  keyboard_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
-                                                  &fh,
-                                                  &read_keyboard_command,
-                                                  NULL);
-}
-
-
-/**
- * @brief Send data to the vmc via the uart bus
- *
- * @param cls closure
- */
-static void
-write_mdb_command (void *cls)
-{
-  int did_write = 0;
-
-  (void) cls;
-  mdb.wtask = NULL;
-
-  if (disable_mdb)
-  {
-    /* check if there is a cmd to send and overwrite last command */
-    if (NULL == mdb.cmd)
-      return;
-    mdb.last_cmd = mdb.cmd;
-    mdb.cmd = NULL;
-    run_mdb_event_loop ();
-    return;
-  }
-  /* if command was sent completely send the rest */
-  if (mdb.tx_off < mdb.tx_len)
-  {
-    ssize_t ret = write (mdb.uartfd,
-                         &mdb.txBuffer[mdb.tx_off],
-                         mdb.tx_len - mdb.tx_off);
-
-    did_write = 1;
-    if (-1 == ret)
-    {
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
-                                "write",
-                                uart_device_filename);
-      if (in_shutdown)
-        mdb_shutdown ();
-      else
-        GNUNET_SCHEDULER_shutdown ();
-      return;
-    }
-    mdb.tx_off += ret;
-    /* if command was sent sucessfully start the timer for ACK timeout */
-    if ( (ret > 0) &&
-         (mdb.tx_off == mdb.tx_len) )
-      mdb.ack_timeout = GNUNET_TIME_relative_to_absolute (MAX_ACK_LATENCY);
-  }
-  /* ongoing write incomplete, continue later */
-  if (mdb.tx_off < mdb.tx_len)
-  {
-    run_mdb_event_loop ();
-    return;
-  }
-  if (NULL != mdb.last_cmd)
-  {
-    struct GNUNET_TIME_Relative del;
-
-    /* Still waiting for ACK! -> delay write task  */
-    del = GNUNET_TIME_absolute_get_remaining (mdb.ack_timeout);
-    if (0 != del.rel_value_us)
-    {
-      if (did_write)
-        run_mdb_event_loop ();
-      else
-        mdb.wtask = GNUNET_SCHEDULER_add_delayed (del,
-                                                  &write_mdb_command,
-                                                  NULL);
-      return;
-    }
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "MDB failed to acknowledge command `%s' within timeout\n",
-                mdb.last_cmd->name);
-    mdb.last_cmd = NULL;
-    if (in_shutdown)
-    {
-      mdb_shutdown ();
-      return;
-    }
-  }
-  if (NULL == mdb.cmd)
-    return;
-  /* if there is a command to send calculate length and checksum */
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Sending command `%s'\n",
-              mdb.cmd->name);
-  mdb.tx_off = 0;
-  mdb.tx_len = mdb.cmd->cmd.bin_size + mdb.cmd->data.bin_size + 1;
-  GNUNET_assert (mdb.tx_len <= sizeof (mdb.txBuffer));
-  {
-    /* calculate checksum: sum up command and data, take just the LSB of the 
result */
-    uint32_t chkSum = 0;
-
-    for (size_t idx = 0; idx < mdb.cmd->cmd.bin_size; idx++)
-      chkSum += mdb.txBuffer[idx] = mdb.cmd->cmd.bin[idx];
-    for (size_t idx = 0; idx < mdb.cmd->data.bin_size; idx++)
-      chkSum += mdb.txBuffer[idx + mdb.cmd->cmd.bin_size] =
-                  mdb.cmd->data.bin[idx];
-    mdb.txBuffer[mdb.cmd->cmd.bin_size + mdb.cmd->data.bin_size] =
-      (uint8_t) (chkSum & 0xFF);
-  }
-  mdb.last_cmd = mdb.cmd;
-  mdb.cmd = NULL;
-  run_mdb_event_loop ();
-}
-
-
-/**
- * @brief MDB acknowledged the last command, proceed.
- */
-static void
-handle_ack ()
-{
-  if (&beginSession == mdb.last_cmd)
-    mdb.session_running = GNUNET_YES;
-  if (&denyVend == mdb.last_cmd)
-  {
-    mdb.session_running = GNUNET_NO;
-    mdb.cmd = &endSession;
-  }
-  mdb.last_cmd = NULL;
-  /* Cause the write-task to be re-scheduled now */
-  if (NULL != mdb.wtask)
-  {
-    GNUNET_SCHEDULER_cancel (mdb.wtask);
-    mdb.wtask = NULL;
-  }
-}
-
-
-/**
- * @brief Parse received command from the VMC
- *
- * @param hex received command from VMC
- * @param hex_len number of characters in @a hex
- */
-static void
-handle_command (const char *hex,
-                size_t hex_len)
-{
-  unsigned int cmd;
-
-  /* if the received command is 0 or not a multiple of 2 we cannot parse it */
-  if (0 == hex_len)
-    return;
-  if (0 != (hex_len % 2))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Received unexpected input `%.*s'\n",
-                (int) hex_len,
-                hex);
-    GNUNET_break_op (0);
-    return;
-  }
-  /* convert the received 2 bytes from ASCII to hex */
-  if (1 != sscanf (hex,
-                   "%2X",
-                   &cmd))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Received non-HEX input `%.*s'\n",
-                (int) hex_len,
-                hex);
-    GNUNET_break_op (0);
-    return;
-  }
-  /* parse the first byte (cmd) and the second byte (subcmd) */
-  switch (cmd)
-  {
-  case VMC_VEND:
-    {
-      unsigned int subcmd;
-
-      GNUNET_break (GNUNET_YES == mdb.session_running);
-      if (4 > hex_len)
-      {
-        GNUNET_break_op (0);
-        return;
-      }
-      if (1 != sscanf (&hex[2],
-                       "%2X",
-                       &subcmd))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    "Received non-HEX input `%.*s'\n",
-                    (int) hex_len - 2,
-                    &hex[2]);
-        GNUNET_break_op (0);
-        return;
-      }
-      switch (subcmd)
-      {
-      case VMC_VEND_REQUEST:
-        {
-          unsigned int product;
-
-          GNUNET_break (GNUNET_YES == mdb.session_running);
-          /* NOTE: hex[4..7] contain the price */
-          if (12 > hex_len)
-          {
-            GNUNET_break_op (0);
-            return;
-          }
-          if (1 != sscanf (&hex[8],
-                           "%4X",
-                           &product))
-          {
-            GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                        "Received non-HEX input `%.*s'\n",
-                        (int) hex_len - 8,
-                        &hex[8]);
-            GNUNET_break_op (0);
-            return;
-          }
-          /* compare the received product number with the defined product 
numbers */
-          for (unsigned int i = 0; i < products_length; i++)
-            if (product == products[i].number)
-            {
-              GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                          "Product %u selected on NFC\n",
-                          product);
-              payment_activity = launch_payment (&products[i]);
-              return;
-            }
-          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                      "Unknown product %u selected on MDB, denying vend\n",
-                      product);
-          mdb.cmd = &denyVend;
-          break;
-        }
-      case VMC_VEND_SUCCESS:
-        GNUNET_break (GNUNET_YES == mdb.session_running);
-        vend_success ();
-        break;
-      case VMC_VEND_FAILURE:
-        {
-          GNUNET_break (GNUNET_YES == mdb.session_running);
-          vend_failure ();
-          break;
-        }
-      case VMC_VEND_SESSION_COMPLETE:
-        {
-          GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                      "Received MDB session complete\n");
-          mdb.session_running = GNUNET_NO;
-          mdb.cmd = &endSession;
-          if (NULL != payment_activity)
-          {
-            cleanup_payment (payment_activity);
-            payment_activity = NULL;
-          }
-        }
-        break;
-      default:
-        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                    "Unknown MDB sub-command %X of command %X\n",
-                    subcmd,
-                    cmd);
-        break;
-      }
-      break;
-    }
-  case VMC_CONF:
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Received request for configuration via MDB\n");
-    mdb.cmd = &readerConfigData;
-    break;
-  case VMC_POLL:
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Received POLL from MDB (ignored)\n");
-    break;
-  case VMC_READER:
-    {
-      unsigned int subcmd;
-
-      if (4 > hex_len)
-      {
-        GNUNET_break_op (0);
-        return;
-      }
-      if (1 != sscanf (&hex[2],
-                       "%2X",
-                       &subcmd))
-      {
-        GNUNET_break_op (0);
-        return;
-      }
-
-      switch (subcmd)
-      {
-      case VMC_READER_DISABLE:
-        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                    "Received Reader Disable via MDB\n");
-        mdb.session_running = GNUNET_NO;
-        if (NULL != payment_activity)
-        {
-          cleanup_payment (payment_activity);
-          payment_activity = NULL;
-        }
-        break;
-      case VMC_READER_ENABLE:
-        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                    "Received Reader Enable via MDB\n");
-        mdb.session_running = GNUNET_NO;
-        break;
-      case VMC_READER_CANCEL:
-        mdb.cmd = &readerCancelled;
-        mdb.session_running = GNUNET_NO;
-        break;
-      default:
-        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                    "Unknown MDB sub-command %X of command %X\n",
-                    subcmd,
-                    cmd);
-        break;
-      }
-      break;
-    }
-  case VMC_REQUEST_ID:
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Received VMC request ID, no need to handle (done by HW)\n");
-    break;
-  case VMC_ACKN:
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Received acknowledgement (for command `%s') from MDB\n",
-                (NULL != mdb.last_cmd) ? mdb.last_cmd->name : "?");
-    handle_ack ();
-    break;
-  case VMC_OOSQ:
-    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;
-    if (mdb.last_cmd != &endSession)
-      mdb.cmd = &endSession;
-    else
-      mdb.last_cmd = NULL;
-    break;
-  case VMC_RETR:
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Received request to resend previous data from MDB (previous 
command was `%s')\n",
-                (NULL != mdb.last_cmd) ? mdb.last_cmd->name : "?");
-    GNUNET_break (NULL == mdb.cmd);
-    GNUNET_break (NULL != mdb.last_cmd);
-    mdb.cmd = mdb.last_cmd;
-    mdb.last_cmd = NULL;
-    break;
-  default:
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Received unknown MDB command %X\n",
-                cmd);
-    break;
-  }
-}
-
-
-/**
- * @brief Read in the sent commands of the VMC controller
- *
- * @param cls closure
- */
-static void
-read_mdb_command (void *cls)
-{
-  ssize_t ret;
-  size_t cmdStartIdx;
-  size_t cmdEndIdx;
-
-  (void) cls;
-  /* don't read if the mdb bus is disabled (only for testing) */
-  GNUNET_assert (! disable_mdb);
-  mdb.rtask = NULL;
-  ret = read (mdb.uartfd,
-              &mdb.rxBuffer[mdb.rx_off],
-              sizeof (mdb.rxBuffer) - mdb.rx_off);
-  if (-1 == ret)
-  {
-    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
-                              "read",
-                              uart_device_filename);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-  mdb.rx_off += ret;
-
-  while (mdb.rx_off > 0)
-  {
-    /* find begining of command */
-    for (cmdStartIdx = 0; cmdStartIdx < mdb.rx_off; cmdStartIdx++)
-      if (VMC_CMD_START == mdb.rxBuffer[cmdStartIdx])
-        break;
-    if (cmdStartIdx == mdb.rx_off)
-    {
-      mdb.rx_off = 0;
-      break;
-    }
-    /* find end of command */
-    for (cmdEndIdx = cmdStartIdx; cmdEndIdx < mdb.rx_off; cmdEndIdx++)
-      if (VMC_CMD_END == mdb.rxBuffer[cmdEndIdx])
-        break;
-    if (cmdEndIdx == mdb.rx_off)
-    {
-      /* check to make sure rxBuffer was big enough in principle */
-      if ( (cmdStartIdx == 0) &&
-           (mdb.rx_off == sizeof (mdb.rxBuffer)) )
-      {
-        /* Developer: if this happens, try increasing rxBuffer! */
-        GNUNET_break (0);
-        GNUNET_SCHEDULER_shutdown ();
-        return;
-      }
-      /* move cmd in buffer to the beginning of the buffer */
-      memmove (mdb.rxBuffer,
-               &mdb.rxBuffer[cmdStartIdx],
-               mdb.rx_off - cmdStartIdx);
-      mdb.rx_off -= cmdStartIdx;
-      break;
-    }
-    /* if the full command was received parse it */
-    handle_command ((const char *) &mdb.rxBuffer[cmdStartIdx + 1],
-                    cmdEndIdx - cmdStartIdx - 1);
-    /* move the data after the processed command to the left */
-    memmove (mdb.rxBuffer,
-             &mdb.rxBuffer[cmdEndIdx + 1],
-             mdb.rx_off - cmdEndIdx + 1);
-    mdb.rx_off -= (cmdEndIdx + 1);
-  }
-  if (in_shutdown)
-  {
-    mdb_shutdown ();
-    return;
-  }
-  run_mdb_event_loop ();
-}
-
-
-/**
- * @brief Mdb event loop to start read and write tasks
- */
-static void
-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) &&
-       (NULL == mdb.cmd) &&
-       (NULL == mdb.last_cmd) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Begining MDB session\n");
-    mdb.cmd = &beginSession;
-  }
-  /* start write task if he doesn't exist and if there is a cmd waiting to get 
sent */
-  if ( (NULL == mdb.wtask) &&
-       ( (NULL != mdb.cmd) ||
-         (in_shutdown) ||
-         (mdb.tx_len > mdb.tx_off) ) )
-  {
-    if (disable_mdb)
-      mdb.wtask = GNUNET_SCHEDULER_add_now (&write_mdb_command,
-                                            NULL);
-    else
-      mdb.wtask = GNUNET_SCHEDULER_add_write_file 
(GNUNET_TIME_UNIT_FOREVER_REL,
-                                                   &fh,
-                                                   &write_mdb_command,
-                                                   NULL);
-  }
-  if ( (disable_mdb) &&
-       (NULL != mdb.last_cmd) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Faking acknowledgement (for command `%s') from MDB\n",
-                mdb.last_cmd->name);
-    handle_ack ();
-  }
-  /* start read task if he doesn't exist and the mdb communication is not 
disabled (only for testing) */
-  if ( (NULL == mdb.rtask) &&
-       (! disable_mdb) )
-    mdb.rtask = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
-                                                &fh,
-                                                &read_mdb_command,
-                                                NULL);
-}
-
-
-/**
- * @brief Read the products from the configuration file
- *
- * @param cls closure
- * @param section section of the config file to read from
- */
-static void
-read_products (void *cls,
-               const char *section)
-{
-  struct Product tmpProduct;
-  char *tmpKey;
-
-  if (0 != strncmp (section,
-                    "product-",
-                    strlen ("product-")))
-    return;
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cls,
-                                             section,
-                                             "description",
-                                             &tmpProduct.description))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               section,
-                               "description");
-    return;
-  }
-  if (GNUNET_OK !=
-      TALER_config_get_denom (cls,
-                              section,
-                              "price",
-                              &tmpProduct.price))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               section,
-                               "price");
-    GNUNET_free (tmpProduct.description);
-    return;
-  }
-  if (0 != strcasecmp (currency,
-                       tmpProduct.price.currency))
-  {
-    GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
-                               section,
-                               "price",
-                               "currency missmatch");
-    GNUNET_free (tmpProduct.description);
-    return;
-  }
-  if (GNUNET_OK ==
-      GNUNET_CONFIGURATION_get_value_string (cls,
-                                             section,
-                                             "key",
-                                             &tmpKey))
-  {
-    tmpProduct.key = tmpKey[0];
-    GNUNET_free (tmpKey);
-  }
-  else
-  {
-    /* no key */
-    tmpProduct.key = '\0';
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_number (cls,
-                                             section,
-                                             "number",
-                                             &tmpProduct.number))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               section,
-                               "number");
-    GNUNET_free (tmpProduct.description);
-    return;
-  }
-  GNUNET_array_append (products,
-                       products_length,
-                       tmpProduct);
-}
-
-
-/**
- * @brief Initialise the uart device to send mdb commands
- */
-static int
-mdb_init ()
-{
-  struct termios uart_opts_raw;
-
-  if (disable_mdb)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Running with MDB disabled!\n");
-    run_mdb_event_loop ();
-    return GNUNET_OK;
-  }
-  /* open uart connection */
-  if (0 > (mdb.uartfd = open (uart_device_filename,
-                              O_RDWR | O_NOCTTY | O_NDELAY)))
-  {
-    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
-                              "open",
-                              uart_device_filename);
-    return GNUNET_SYSERR;
-  }
-
-  if (0 != tcgetattr (mdb.uartfd, &mdb.uart_opts_backup))
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                         "tcgetattr");
-    return GNUNET_SYSERR;
-  }
-  uart_opts_raw = mdb.uart_opts_backup;
-
-  /* reset current uart discipline */
-  memset (&uart_opts_raw,
-          0,
-          sizeof(uart_opts_raw));
-
-  /* set baudrate */
-  cfsetispeed (&uart_opts_raw, B9600);
-  cfsetospeed (&uart_opts_raw, B9600);
-
-  /* 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;
-  tcflush (mdb.uartfd, TCIOFLUSH);
-  if (0 != tcsetattr (mdb.uartfd,
-                      TCSAFLUSH,
-                      &uart_opts_raw))
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                         "tcsetattr");
-    return GNUNET_SYSERR;
-  }
-  /* if the configuration of the uart was sucessfull start the mdb write and 
read tasks */
-  run_mdb_event_loop ();
-  return GNUNET_OK;
-}
-
-
-/**
- * @brief Start the application
- *
- * @param cls closure
- * @param args arguments left
- * @param cfgfile config file name
- * @param cfg handle for the configuation file
- */
-static void
-run (void *cls,
-     char *const *args,
-     const char *cfgfile,
-     const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
-  (void) cls;
-  (void) args;
-  (void) cfgfile;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cfg,
-                                             "taler",
-                                             "currency",
-                                             &currency))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "taler",
-                               "currency");
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (cfg,
-                                               "taler-mdb",
-                                               "UART_DEVICE",
-                                               &uart_device_filename))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "taler-mdb",
-                               "UART_DEVICE");
-    uart_device_filename = GNUNET_strdup ("/dev/ttyAMA0");
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (cfg,
-                                               "taler-mdb",
-                                               "FRAMEBUFFER_DEVICE",
-                                               &framebuffer_device_filename))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "taler-mdb",
-                               "FRAMEBUFFER_DEVICE");
-    framebuffer_device_filename = GNUNET_strdup ("/dev/fb1");
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (cfg,
-                                               "taler-mdb",
-                                               "FRAMEBUFFER_BACKLIGHT",
-                                               
&framebuffer_backlight_filename))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "taler-mdb",
-                               "FRAMEBUFFER_BACKLIGHT");
-    framebuffer_backlight_filename = GNUNET_strdup (
-      "/sys/class/backlight/soc:backlight/brightness");
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cfg,
-                                             "taler-mdb",
-                                             "backend-base-url",
-                                             &backendBaseUrl))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "taler-mdb",
-                               "backend-base-url");
-    global_ret = EXIT_FAILURE;
-    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;
-    }
-    GNUNET_asprintf (&authorization,
-                     "%s: %s",
-                     MHD_HTTP_HEADER_AUTHORIZATION,
-                     auth);
-    GNUNET_free (auth);
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cfg,
-                                             "taler-mdb",
-                                             "fulfillment-url",
-                                             &fulfillmentUrl))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "taler-mdb",
-                               "fulfillment-url");
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cfg,
-                                             "taler-mdb",
-                                             "fulfillment-msg",
-                                             &fulfillmentMsg))
-  {
-    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "taler-mdb",
-                               "fulfillment-msgcurrency");
-    global_ret = EXIT_FAILURE;
-    return;
-  }
-  GNUNET_CONFIGURATION_iterate_sections (cfg,
-                                         &read_products,
-                                         (void *) cfg);
-  GNUNET_assert (NULL != products);
-
-  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
-                                 NULL);
-
-  /* initialize mdb */
-  if (GNUNET_OK != mdb_init ())
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unable to initialize MDB (mdb_init() failed)\n");
-    global_ret = EXIT_FAILURE;
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
-
-  /* initialize nfc */
-  nfc_init (&context);
-  if (NULL == context)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "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));
-
-#if HAVE_QRENCODE_H
-  /* open the framebuffer device */
-  qrDisplay.devicefd = open (framebuffer_device_filename,
-                             O_RDWR);
-  if (0 < qrDisplay.devicefd)
-  {
-    /* read information about the screen */
-    ioctl (qrDisplay.devicefd,
-           FBIOGET_VSCREENINFO,
-           &qrDisplay.var_info);
-
-    /* store current screeninfo for reset */
-    qrDisplay.orig_vinfo = qrDisplay.var_info;
-
-    if (16 != qrDisplay.var_info.bits_per_pixel)
-    {
-      /* Change variable info to 16 bit per pixel */
-      qrDisplay.var_info.bits_per_pixel = 16;
-      if (0 > ioctl (qrDisplay.devicefd,
-                     FBIOPUT_VSCREENINFO,
-                     &qrDisplay.var_info))
-      {
-        GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                             "ioctl(FBIOPUT_VSCREENINFO)");
-        return;
-      }
-    }
-
-    /* Get fixed screen information */
-    if (0 > ioctl (qrDisplay.devicefd,
-                   FBIOGET_FSCREENINFO,
-                   &qrDisplay.fix_info))
-    {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                           "ioctl(FBIOGET_FSCREENINFO)");
-      return;
-    }
-
-    /* get pointer onto frame buffer */
-    qrDisplay.memory =  mmap (NULL,
-                              qrDisplay.fix_info.smem_len,
-                              PROT_READ | PROT_WRITE, MAP_SHARED,
-                              qrDisplay.devicefd,
-                              0);
-
-    /* open backlight file to turn display backlight on and off */
-    if (0 > qrDisplay.devicefd)
-    {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                           "mmap");
-      return;
-    }
-
-    memset (qrDisplay.memory,
-            0xFF,
-            qrDisplay.var_info.xres * qrDisplay.var_info.yres
-            * sizeof (uint16_t));
-
-    qrDisplay.backlightfd = open (
-      framebuffer_backlight_filename, O_WRONLY);
-    if (0 > qrDisplay.backlightfd)
-    {
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
-                                "open",
-                                framebuffer_backlight_filename);
-    }
-    else
-    {
-      if (backlight_invert)
-      {
-        backlight_on = '0';
-        backlight_off = '1';
-      }
-      (void) write (qrDisplay.backlightfd, &backlight_off, 1);
-    }
-  }
-  else
-  {
-    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
-                              "open",
-                              framebuffer_device_filename);
-  }
-#endif
-  if (! disable_tty)
-    start_read_keyboard ();
-}
-
-
-/**
- * @brief Convert the ASCII cmd in @hex to hex and store it in the mdb data 
struct @blk
- *
- * @param *blk pointer with reference to the mdb datablock
- * @param *hex pointer to the string containing the cmd data
- */
-static void
-parse_block (struct MdbBlock *blk,
-             const char *hex)
-{
-  if (NULL == hex)
-  {
-    blk->bin_size = 0;
-    blk->bin = NULL;
-    return;
-  }
-  blk->bin_size = strlen (hex) / 2;
-  blk->bin = GNUNET_malloc (blk->bin_size);
-  for (size_t idx = 0; idx < blk->bin_size; idx++)
-  {
-    unsigned int val;
-
-    GNUNET_assert (1 ==
-                   sscanf (&hex[idx * 2],
-                           "%2X",
-                           &val));
-    blk->bin[idx] = (uint8_t) val;
-  }
-}
-
-
-/**
- * @brief Create a new mdb command
- *
- * @param *name pointer to the string containing the command name
- * @param *cmd pointer to the string containing the command
- * @param *data pointer to the string containing the command data
- * @return structure of type MdbCommand holding the given information by the 
parameters
- */
-static struct MdbCommand
-setup_mdb_cmd (const char *name,
-               const char *cmd,
-               const char *data)
-{
-  struct MdbCommand cmdNew;
-
-  cmdNew.name = (NULL == name)
-                ? "No Cmd Name Set"
-                : name;
-  parse_block (&cmdNew.cmd, cmd);
-  parse_block (&cmdNew.data, data);
-  return cmdNew;
-}
-
-
-int
-main (int argc,
-      char*const*argv)
-{
-  struct termios tty_opts_backup, tty_opts_raw;
-  int ret;
-  /* the available command line options */
-  struct GNUNET_GETOPT_CommandLineOption options[] = {
-    GNUNET_GETOPT_option_flag ('d',
-                               "disable-mdb",
-                               "disable all interactions with the MDB (for 
testing without machine)",
-                               &disable_mdb),
-    GNUNET_GETOPT_option_flag ('t',
-                               "disable-tty",
-                               "disable all keyboard interactions (for running 
from systemd)",
-                               &disable_tty),
-    GNUNET_GETOPT_option_flag ('i',
-                               "backlight-invert",
-                               "invert the backlight on/off values (standard 
on = 1)",
-                               &backlight_invert),
-    GNUNET_GETOPT_OPTION_END
-  };
-  int have_tty;
-
-  if (! disable_tty)
-  {
-    have_tty = isatty (STDIN_FILENO);
-    if (have_tty)
-    {
-      if (0 != tcgetattr (STDIN_FILENO, &tty_opts_backup))
-        fprintf (stderr,
-                 "Failed to get terminal discipline\n");
-      tty_opts_raw = tty_opts_backup;
-      tty_opts_raw.c_lflag &= ~(ECHO | ECHONL | ICANON);
-      if (0 != tcsetattr (STDIN_FILENO, TCSANOW, &tty_opts_raw))
-        fprintf (stderr,
-                 "Failed to set terminal discipline\n");
-    }
-  }
-  /* make the needed commands for the communication with the vending machine 
controller */
-  readerConfigData = setup_mdb_cmd ("Reader Config",
-                                    READER_CONFIG,
-                                    READER_FEATURE_LEVEL READER_COUNTRYCODE
-                                    READER_SCALE_FACTOR READER_DECIMAL_PLACES
-                                    READER_MAX_RESPONSE_TIME
-                                    READER_MISC_OPTIONS);
-  beginSession = setup_mdb_cmd ("Begin Session",
-                                READER_BEGIN_SESSION,
-                                READER_FUNDS_AVAILABLE);
-  approveVend = setup_mdb_cmd ("Approve Vend",
-                               READER_VEND_APPROVE,
-                               READER_VEND_AMOUNT);
-  readerCancelled = setup_mdb_cmd ("Confirm cancellation",
-                                   READER_CANCELLED,
-                                   NULL);
-  denyVend = setup_mdb_cmd ("Deny Vend",
-                            READER_VEND_DENIED,
-                            NULL);
-  endSession = setup_mdb_cmd ("End Session",
-                              READER_END_SESSION,
-                              NULL);
-
-  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);
-  if (! disable_tty)
-  {
-    if (have_tty)
-    {
-      /* Restore previous TTY settings */
-      if (0 != tcsetattr (STDIN_FILENO,
-                          TCSANOW,
-                          &tty_opts_backup))
-        fprintf (stderr,
-                 "Failed to restore terminal discipline\n");
-    }
-  }
-  if (GNUNET_OK != ret)
-    return 1;
-  return global_ret;
-}

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]