summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-01-24 12:27:54 +0100
committerChristian Grothoff <christian@grothoff.org>2020-01-24 12:36:05 +0100
commit09cf0428c632ad6698315b78b2f6a4db69c1d4a8 (patch)
tree7c1a48361328067ae439ad5c6ac38bd3195dba72
parent237dbf9290ab2198894a703149eb1a5e2347da73 (diff)
parent1e464cbc9e230895ad3cee64f83bc4452b12e767 (diff)
downloadtaler-mdb-09cf0428c632ad6698315b78b2f6a4db69c1d4a8.tar.gz
taler-mdb-09cf0428c632ad6698315b78b2f6a4db69c1d4a8.tar.bz2
taler-mdb-09cf0428c632ad6698315b78b2f6a4db69c1d4a8.zip
fix style issues
-rw-r--r--src/main.c486
-rw-r--r--taler.conf82
2 files changed, 408 insertions, 160 deletions
diff --git a/src/main.c b/src/main.c
index 3110a13..a1cdcfc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -23,8 +23,6 @@ along with
* @author Christian Grothoff
* @author Dominik Hofer
*
-* TODO:
-* - comment code mdb incl. doxygen struct members (hofer)
*/
#include "config.h"
#include <stdio.h>
@@ -71,7 +69,9 @@ along with
*/
#define _(s) (s)
-#define BACKEND_POLL_TIMEOUT GNUNET_TIME_UNIT_MINUTES
+/* FIXME Adjusted Time out because low internet connection at 36C3 */
+#define BACKEND_POLL_TIMEOUT GNUNET_TIME_relative_multiply ( \
+ GNUNET_TIME_UNIT_MINUTES, 5)
#define NFC_FAILURE_RETRY_FREQ GNUNET_TIME_UNIT_SECONDS
@@ -125,6 +125,7 @@ along with
/* VMC commands */
#define VMC_CMD_START 0x02
#define VMC_CMD_END 0x03
+#define VMC_CMD_RESET 0x10
/**
* Acknowledgement
@@ -135,6 +136,8 @@ along with
* Request for configuration.
*/
#define VMC_CONF 0x11
+#define VMC_READER_CONF 0x00
+#define VMC_SETUP_MAX_MIN_PRICES 0x01
/**
* Machine is polling for something.
@@ -179,6 +182,9 @@ along with
/* Reader commands */
+/* Reader Not Acknowledge */
+#define READER_NACK "FF"
+
/* Config Data */
/* Refer to the mdb interface specifications v4.2 p.288 */
#define READER_CONFIG "01"
@@ -210,8 +216,17 @@ along with
/* Cancelled Command */
#define READER_CANCELLED "08"
-/* Unused reader commands */
+/* Display Request for Sold Out product */
#define READER_DISPLAY_REQUEST "02"
+#define READER_DISPLAY_REQUEST_TIME "32"
+#define READER_DISPLAY_SOLD_OUT \
+ "202020202020202050726f6475637420736f6c64206f75742020202020202020"
+#define READER_DISPLAY_INTERNAL_ERROR \
+ "202020496e7465726e616c204572726f72202d2054727920416761696e202020i"
+#define READER_DISPLAY_BACKEND_NOT_REACHABLE \
+ "20202020204261636b656e64206e6f7420726561636861626c65202020202020"
+
+/* Unused reader commands */
#define READER_SESSION_CANCEL_REQUEST "04"
#define READER_REVALUE_DENIED "0E"
@@ -227,8 +242,14 @@ along with
*/
struct MdbBlock
{
+ /**
+ * Data containing a mdb command or the data of an mdb command
+ */
uint8_t *bin;
+ /**
+ * Size of the data referenced by *bin
+ */
size_t bin_size;
};
@@ -238,10 +259,19 @@ struct MdbBlock
*/
struct MdbCommand
{
+ /**
+ * Name of the command for the logging
+ */
const char *name;
+ /**
+ * Data block containing the information about the mdb command
+ */
struct MdbBlock cmd;
+ /**
+ * Data block containing the information about the mdb command data
+ */
struct MdbBlock data;
};
@@ -361,18 +391,39 @@ struct PaymentActivity
struct MdbHandle
{
+ /**
+ * Buffer to save the received data from UART
+ */
uint8_t rxBuffer[MAX_SIZE_RX_BUFFER];
+ /**
+ * Buffer to save the data to send via UART
+ */
uint8_t txBuffer[MAX_SIZE_TX_BUFFER];
+ /**
+ * Reference to scheduler task to read from UART
+ */
struct GNUNET_SCHEDULER_Task *rtask;
+ /**
+ * Reference to scheduler task to write to UART
+ */
struct GNUNET_SCHEDULER_Task *wtask;
+ /**
+ * Reference to the mdb cmd which will be sent next
+ */
const struct MdbCommand *cmd;
+ /**
+ * Reference to the mdb cmd which was sent last
+ */
const struct MdbCommand *last_cmd;
+ /**
+ * Current read offset in @e rxBuffer.
+ */
size_t rx_off;
/**
@@ -386,12 +437,24 @@ struct MdbHandle
*/
size_t tx_len;
+ /**
+ * Time out to wait for an acknoweledge received via the mdb bus
+ */
struct GNUNET_TIME_Absolute ack_timeout;
+ /**
+ * Backup of the config data to restore the configuration of the UART before closing it
+ */
struct termios uart_opts_backup;
+ /**
+ * Indicates if a vend session is running or not
+ */
int session_running;
+ /**
+ * File descriptor to the UART device file
+ */
int uartfd;
};
@@ -434,6 +497,18 @@ struct Display
};
/**
+ * Handle for the Cancel Button
+ */
+struct CancelButton
+{
+ /**
+ * File descriptor to read the state of the cancel button gpio pin
+ */
+ int cancelbuttonfd;
+};
+
+
+/**
* DLL of pending refund operations.
*/
struct Refund
@@ -515,17 +590,17 @@ static char *currency;
/**
* Taler Backend url read from configuration file
*/
-static char *backendBaseUrl;
+static char *backend_base_url;
/**
* Taler fulfillment url read from configuration file
*/
-static char *fulfillmentUrl;
+static char *fulfillment_url;
/**
* Fulfillment message to display after successfull payment, read from configuration file
*/
-static char *fulfillmentMsg;
+static char *fulfillment_msg;
/**
* Authorization for the taler backend
@@ -555,37 +630,57 @@ static struct MdbHandle mdb;
/**
* MDB response to the request for configuration.
*/
-static struct MdbCommand readerConfigData;
+static struct MdbCommand cmd_reader_config_data;
/**
* Ask MDB to begin session (with "infinite" money)
*/
-static struct MdbCommand beginSession;
+static struct MdbCommand cmd_begin_session;
/**
* Refuse vending request (payment failed)
*/
-static struct MdbCommand denyVend;
+static struct MdbCommand cmd_deny_vend;
/**
* Approve vending request (payment succeeded)
*/
-static struct MdbCommand approveVend;
+static struct MdbCommand cmd_approve_vend;
/**
* Confirm cancellation by machine.
*/
-static struct MdbCommand readerCancelled;
+static struct MdbCommand cmd_reader_cancelled;
/**
* Approve Revalue
*/
-static struct MdbCommand revalueApproved;
+static struct MdbCommand cmd_revalue_approved;
/**
* Send Revalue Limit Amount
*/
-static struct MdbCommand revalueAmount;
+static struct MdbCommand cmd_revalue_amount;
+
+/**
+ * Send NACK
+ */
+static struct MdbCommand cmd_reader_NACK;
+
+/**
+ * Display Request for Sold Out
+ */
+static struct MdbCommand cmd_reader_display_sold_out;
+
+/**
+ * Display Request for Error Message
+ */
+static struct MdbCommand cmd_reader_display_internal_error;
+
+/**
+ * Display Request for Error Message
+ */
+static struct MdbCommand cmd_reader_display_backend_not_reachable;
/**
* Terminate session.
@@ -620,12 +715,7 @@ static char backlight_off = '0';
/**
* State for the implementation of the 'cancel' button.
*/
-struct CancelButton
-{
- int cancelbuttonfd;
-};
-
-static struct CancelButton cancelButton;
+static struct CancelButton cancel_button;
/**
* Name of the UART device with the MDB (i.e. /dev/ttyAMA0).
@@ -817,6 +907,11 @@ cleanup_payment (struct PaymentActivity *pa)
nfc_abort_command (pa->pnd);
nfc_close (pa->pnd);
}
+ if (NULL != cancelbutton_task)
+ {
+ GNUNET_SCHEDULER_cancel (cancelbutton_task);
+ cancelbutton_task = NULL;
+ }
if (NULL != pa->po)
TALER_MERCHANT_proposal_cancel (pa->po);
if (NULL != pa->cpo)
@@ -850,7 +945,7 @@ cleanup_payment (struct PaymentActivity *pa)
* @brief Shutdown the mdb communication tasks
*/
static void
-mdb_shutdown ()
+mdb_shutdown (void)
{
if (NULL != mdb.rtask)
{
@@ -917,6 +1012,11 @@ shutdown_task (void *cls)
cleanup_payment (payment_activity);
payment_activity = NULL;
}
+ if (NULL != cancelbutton_task)
+ {
+ GNUNET_SCHEDULER_cancel (cancelbutton_task);
+ cancelbutton_task = NULL;
+ }
if (NULL != keyboard_task)
{
GNUNET_SCHEDULER_cancel (keyboard_task);
@@ -959,18 +1059,18 @@ shutdown_task (void *cls)
close (qrDisplay.backlightfd);
qrDisplay.backlightfd = -1;
}
- if (0 < cancelButton.cancelbuttonfd)
+ if (0 < cancel_button.cancelbuttonfd)
{
- close (cancelButton.cancelbuttonfd);
- cancelButton.cancelbuttonfd = open ("/sys/class/gpio/unexport",
- O_WRONLY);
- if (0 > cancelButton.cancelbuttonfd)
+ close (cancel_button.cancelbuttonfd);
+ cancel_button.cancelbuttonfd = open ("/sys/class/gpio/unexport",
+ O_WRONLY);
+ if (0 > cancel_button.cancelbuttonfd)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unable to open /gpio/unexport for cancel button\n");
}
- (void) write (cancelButton.cancelbuttonfd, "17", 2);
- close (cancelButton.cancelbuttonfd);
+ (void) write (cancel_button.cancelbuttonfd, "23", 2);
+ close (cancel_button.cancelbuttonfd);
}
/* free the allocated productes read from config file */
if (NULL != products)
@@ -1271,7 +1371,7 @@ check_payment_cb (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Backend request to /check-payment failed: %u\n",
http_status);
- mdb.cmd = &denyVend;
+ mdb.cmd = &cmd_reader_display_backend_not_reachable;
run_mdb_event_loop ();
cleanup_payment (pa);
GNUNET_assert (payment_activity == pa);
@@ -1281,7 +1381,7 @@ check_payment_cb (void *cls,
if (paid)
{
- mdb.cmd = &approveVend;
+ mdb.cmd = &cmd_approve_vend;
payment_activity->paid = GNUNET_YES;
run_mdb_event_loop ();
if ((disable_mdb) && (! disable_tty))
@@ -1335,7 +1435,7 @@ check_payment_again (void *cls)
pa->delay_pay_task = NULL;
GNUNET_assert (NULL == pa->cpo);
pa->cpo = TALER_MERCHANT_check_payment (ctx,
- backendBaseUrl,
+ backend_base_url,
pa->order_id,
NULL /* snack machine, no Web crap */,
BACKEND_POLL_TIMEOUT,
@@ -1370,7 +1470,7 @@ proposal_cb (void *cls,
"Failed to setup order with backend: %u/%d\n",
http_status,
(int) ec);
- mdb.cmd = &denyVend;
+ mdb.cmd = &cmd_reader_display_backend_not_reachable;
run_mdb_event_loop ();
cleanup_payment (pa);
GNUNET_assert (payment_activity == pa);
@@ -1382,7 +1482,7 @@ proposal_cb (void *cls,
order_id);
pa->order_id = GNUNET_strdup (order_id);
pa->cpo = TALER_MERCHANT_check_payment (ctx,
- backendBaseUrl,
+ backend_base_url,
pa->order_id,
NULL /* snack machine, no Web crap */,
GNUNET_TIME_UNIT_ZERO,
@@ -1419,8 +1519,8 @@ launch_payment (struct Product *product)
/* create the fulfillment url, e.g. "taler://fulfillment-success/Enjoy+your+ice+cream!"; */
GNUNET_asprintf (&fulflmntUrl,
"%s%s%s#%s",
- fulfillmentUrl,
- fulfillmentMsg,
+ fulfillment_url,
+ fulfillment_msg,
product->description,
uuid_s);
GNUNET_free (uuid_s);
@@ -1444,7 +1544,7 @@ launch_payment (struct Product *product)
pa->amount = product->price;
/* put the order on the merchant's backend */
pa->po = TALER_MERCHANT_order_put (ctx,
- backendBaseUrl,
+ backend_base_url,
orderReq,
&proposal_cb,
pa);
@@ -1456,7 +1556,8 @@ launch_payment (struct Product *product)
GNUNET_free (pa);
return NULL;
}
- if (0 < cancelButton.cancelbuttonfd)
+ /* Start to read the button on the VM to cancel this payment */
+ if (0 < cancel_button.cancelbuttonfd)
start_read_cancel_button ();
return pa;
}
@@ -1534,7 +1635,7 @@ vend_failure ()
mdb.session_running = GNUNET_NO;
r = GNUNET_new (struct Refund);
r->rio = TALER_MERCHANT_refund_increase (ctx,
- backendBaseUrl,
+ backend_base_url,
payment_activity->order_id,
&payment_activity->amount,
"failed to dispense product",
@@ -1586,7 +1687,7 @@ read_keyboard_command (void *cls)
case 'c':
if (GNUNET_NO == payment_activity->paid)
{
- mdb.cmd = &denyVend;
+ mdb.cmd = &cmd_deny_vend;
}
else
{
@@ -1599,7 +1700,7 @@ read_keyboard_command (void *cls)
break;
case 'a':
payment_activity->paid = GNUNET_YES;
- mdb.cmd = &approveVend;
+ mdb.cmd = &cmd_approve_vend;
run_mdb_event_loop ();
break;
case 'n':
@@ -1644,12 +1745,12 @@ read_keyboard_command (void *cls)
if (((char) input) == products[i].key)
{
if ( (sold_out_enabled) &&
- (products[i].sold_out) )
+ (GNUNET_YES == products[i].sold_out) )
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Product %s sold out, denying vend\n",
products[i].description);
- mdb.cmd = &denyVend;
+ mdb.cmd = &cmd_reader_display_sold_out;
run_mdb_event_loop ();
start_read_keyboard ();
return;
@@ -1664,6 +1765,11 @@ read_keyboard_command (void *cls)
start_read_keyboard ();
}
+/**
+ * @brief Read the state of the cancel button GPIO pin
+ *
+ * @param cls closure
+ */
static void
cancel_button_pressed (void *cls)
{
@@ -1671,28 +1777,37 @@ cancel_button_pressed (void *cls)
char value;
cancelbutton_task = NULL;
- read (cancelButton.cancelbuttonfd, &value, 1);
- lseek (cancelButton.cancelbuttonfd, 0, SEEK_SET);
- if ( '1' == value )
+ read (cancel_button.cancelbuttonfd, &value, 1);
+ lseek (cancel_button.cancelbuttonfd, 0, SEEK_SET);
+ /* This point should only be reached when a order is pending, because
+ * the scheduler read file gets added in the function "launch_payment".
+ * But anyway safe check, else do nothing */
+ if (NULL != payment_activity)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Cancel button pressed, canceling current order\n");
- if (GNUNET_NO == payment_activity->paid)
+ if ('1' == value)
{
- mdb.cmd = &denyVend;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Cancel button pressed, canceling current order\n");
+ if (GNUNET_NO == payment_activity->paid)
+ {
+ /* The current payment was not paid already, deny it */
+ mdb.cmd = &cmd_deny_vend;
+ }
+ else
+ {
+ /* 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;
+ }
+ run_mdb_event_loop ();
+ cleanup_payment (payment_activity);
+ payment_activity = NULL;
}
else
{
- mdb.cmd = &endSession;
- mdb.session_running = GNUNET_NO;
+ start_read_cancel_button ();
}
- run_mdb_event_loop ();
- cleanup_payment (payment_activity);
- payment_activity = NULL;
- }
- else
- {
- start_read_cancel_button ();
}
}
@@ -1735,10 +1850,13 @@ start_read_keyboard ()
NULL);
}
+/**
+ * @brief Wait for cancel button during payment activity
+ */
static void
start_read_cancel_button ()
{
- struct GNUNET_DISK_FileHandle fh = { cancelButton.cancelbuttonfd };
+ struct GNUNET_DISK_FileHandle fh = { cancel_button.cancelbuttonfd };
GNUNET_assert (NULL == cancelbutton_task);
cancelbutton_task = GNUNET_SCHEDULER_add_read_file (
@@ -1863,13 +1981,19 @@ write_mdb_command (void *cls)
static void
handle_ack ()
{
- if (&beginSession == mdb.last_cmd)
+ if (&cmd_begin_session == mdb.last_cmd)
mdb.session_running = GNUNET_YES;
- if (&denyVend == mdb.last_cmd)
+ if (&cmd_deny_vend == mdb.last_cmd)
{
mdb.session_running = GNUNET_NO;
mdb.cmd = &endSession;
}
+ if (&cmd_reader_display_sold_out == mdb.last_cmd)
+ mdb.cmd = &cmd_deny_vend;
+ if (&cmd_reader_display_internal_error == mdb.last_cmd)
+ mdb.cmd = &cmd_deny_vend;
+ if (&cmd_reader_display_backend_not_reachable == mdb.last_cmd)
+ mdb.cmd = &cmd_deny_vend;
mdb.last_cmd = NULL;
/* Cause the write-task to be re-scheduled now */
if (NULL != mdb.wtask)
@@ -1891,6 +2015,8 @@ handle_command (const char *hex,
size_t hex_len)
{
unsigned int cmd;
+ unsigned int tmp = 0;
+ uint32_t chkSum;
/* if the received command is 0 or not a multiple of 2 we cannot parse it */
if (0 == hex_len)
@@ -1916,6 +2042,7 @@ handle_command (const char *hex,
GNUNET_break_op (0);
return;
}
+
/* parse the first byte (cmd) and the second byte (subcmd) */
switch (cmd)
{
@@ -1944,6 +2071,34 @@ handle_command (const char *hex,
{
case VMC_VEND_REQUEST:
{
+
+ /* Calculate the checksum and check it */
+ chkSum = cmd;
+
+ for ( size_t offset = 1; offset < ((hex_len / 2)); offset++ ) {
+ chkSum += tmp;
+ if (1 != sscanf (hex + (2 * offset),
+ "%2X",
+ &tmp))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Received non-HEX input `%.*s'\n",
+ (int) hex_len,
+ hex);
+ GNUNET_break_op (0);
+ return;
+ }
+ }
+ if ( ((uint8_t) (chkSum & 0xFF)) != tmp )
+ {
+ mdb.cmd = &cmd_reader_display_internal_error;
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Received command with wrong checksum `%.*s'\n",
+ (int) hex_len,
+ hex);
+ break;
+
+ }
unsigned int product;
GNUNET_break (GNUNET_YES == mdb.session_running);
@@ -1969,15 +2124,15 @@ handle_command (const char *hex,
if (product == products[i].number)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Product %u selected on NFC\n",
+ "Product %u selected on MDB\n",
product);
if ( (sold_out_enabled) &&
- (products[i].sold_out) )
+ (GNUNET_YES == products[i].sold_out) )
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Product %s sold out, denying vend\n",
products[i].description);
- mdb.cmd = &denyVend;
+ mdb.cmd = &cmd_reader_display_sold_out;
return;
}
payment_activity = launch_payment (&products[i]);
@@ -1986,7 +2141,7 @@ handle_command (const char *hex,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unknown product %u selected on MDB, denying vend\n",
product);
- mdb.cmd = &denyVend;
+ mdb.cmd = &cmd_deny_vend;
break;
}
case VMC_VEND_SUCCESS:
@@ -2047,14 +2202,14 @@ handle_command (const char *hex,
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received request for revalue via MDB\n");
- mdb.cmd = &revalueApproved;
+ mdb.cmd = &cmd_revalue_approved;
break;
}
case VMC_REVALUE_LIMIT_REQUEST:
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received request for revalue limit amount via MDB\n");
- mdb.cmd = &revalueAmount;
+ mdb.cmd = &cmd_revalue_amount;
break;
}
default:
@@ -2067,14 +2222,60 @@ handle_command (const char *hex,
break;
}
case VMC_CONF:
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Received request for configuration via MDB\n");
- mdb.cmd = &readerConfigData;
- break;
+ {
+ unsigned int subcmd;
+
+ 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_READER_CONF:
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Received request for configuration via MDB\n");
+ mdb.cmd = &cmd_reader_config_data;
+ break;
+
+ }
+ case VMC_SETUP_MAX_MIN_PRICES:
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Received max and min prices via MDB\n");
+ break;
+ }
+ default:
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Unknown MDB sub-command %X of command %X\n",
+ subcmd,
+ cmd);
+ break;
+ }
+ break;
+ }
case VMC_POLL:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received POLL from MDB (ignored)\n");
break;
+ case VMC_CMD_RESET:
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received RESET from MDB (ignored)\n");
+ break;
+ }
case VMC_READER:
{
unsigned int subcmd;
@@ -2103,6 +2304,19 @@ handle_command (const char *hex,
cleanup_payment (payment_activity);
payment_activity = NULL;
}
+ for (unsigned int i = 0; i < products_length; i++)
+ {
+ if ( (sold_out_enabled) &&
+ (0 != strcmp (products[i].description,
+ "empty")) &&
+ (GNUNET_YES == 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;
+ }
+ }
break;
case VMC_READER_ENABLE:
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -2110,7 +2324,7 @@ handle_command (const char *hex,
mdb.session_running = GNUNET_NO;
break;
case VMC_READER_CANCEL:
- mdb.cmd = &readerCancelled;
+ mdb.cmd = &cmd_reader_cancelled;
mdb.session_running = GNUNET_NO;
break;
default:
@@ -2256,7 +2470,7 @@ run_mdb_event_loop ()
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Begining MDB session\n");
- mdb.cmd = &beginSession;
+ mdb.cmd = &cmd_begin_session;
}
/* start write task if he doesn't exist and if there is a cmd waiting to get sent */
if ( (NULL == mdb.wtask) &&
@@ -2324,11 +2538,23 @@ read_products (void *cls,
"description");
return;
}
+ if (sold_out_enabled)
+ {
+ if (0 == strcmp (tmpProduct.description,
+ "empty"))
+ {
+ tmpProduct.sold_out = GNUNET_YES;
+ }
+ else
+ {
+ tmpProduct.sold_out = GNUNET_NO;
+ }
+ }
if (GNUNET_OK !=
- TALER_config_get_denom (cls,
- section,
- "price",
- &tmpProduct.price))
+ TALER_config_get_amount (cls,
+ section,
+ "price",
+ &tmpProduct.price))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
section,
@@ -2520,7 +2746,7 @@ run (void *cls,
GNUNET_CONFIGURATION_get_value_string (cfg,
"taler-mdb",
"backend-base-url",
- &backendBaseUrl))
+ &backend_base_url))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler-mdb",
@@ -2553,7 +2779,7 @@ run (void *cls,
GNUNET_CONFIGURATION_get_value_string (cfg,
"taler-mdb",
"fulfillment-url",
- &fulfillmentUrl))
+ &fulfillment_url))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler-mdb",
@@ -2565,7 +2791,7 @@ run (void *cls,
GNUNET_CONFIGURATION_get_value_string (cfg,
"taler-mdb",
"fulfillment-msg",
- &fulfillmentMsg))
+ &fulfillment_msg))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler-mdb",
@@ -2613,32 +2839,32 @@ run (void *cls,
authorization));
/* open gpio pin for cance button */
- cancelButton.cancelbuttonfd = open ("/sys/class/gpio/export",
- O_WRONLY);
- if (0 > cancelButton.cancelbuttonfd)
+ cancel_button.cancelbuttonfd = open ("/sys/class/gpio/export",
+ O_WRONLY);
+ if (0 > cancel_button.cancelbuttonfd)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unable to open /gpio/export for cancel button\n");
}
- (void) write (cancelButton.cancelbuttonfd, "17", 2);
- close (cancelButton.cancelbuttonfd);
+ (void) write (cancel_button.cancelbuttonfd, "23", 2);
+ close (cancel_button.cancelbuttonfd);
- cancelButton.cancelbuttonfd = open ("/sys/class/gpio/gpio17/direction",
- O_WRONLY);
- if (0 > cancelButton.cancelbuttonfd)
+ cancel_button.cancelbuttonfd = open ("/sys/class/gpio/gpio23/direction",
+ O_WRONLY);
+ if (0 > cancel_button.cancelbuttonfd)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Unable to open /gpio/gpio17/direction for cancel button\n");
+ "Unable to open /gpio/gpio23/direction for cancel button\n");
}
- (void) write (cancelButton.cancelbuttonfd, "in", 2);
- close (cancelButton.cancelbuttonfd);
+ (void) write (cancel_button.cancelbuttonfd, "in", 2);
+ close (cancel_button.cancelbuttonfd);
- cancelButton.cancelbuttonfd = open ("/sys/class/gpio/gpio17/value",
- O_RDONLY);
- if (0 > cancelButton.cancelbuttonfd)
+ cancel_button.cancelbuttonfd = open ("/sys/class/gpio/gpio23/value",
+ O_RDONLY);
+ if (0 > cancel_button.cancelbuttonfd)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Unable to open /gpio/gpio17/value for cancel button\n");
+ "Unable to open /gpio/gpio23/value for cancel button\n");
}
@@ -2832,35 +3058,57 @@ main (int argc,
}
}
/* 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);
+ cmd_reader_config_data = 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);
+ cmd_begin_session = setup_mdb_cmd ("Begin Session",
+ READER_BEGIN_SESSION,
+ READER_FUNDS_AVAILABLE);
+ cmd_approve_vend = setup_mdb_cmd ("Approve Vend",
+ READER_VEND_APPROVE,
+ READER_VEND_AMOUNT);
+ cmd_reader_cancelled = setup_mdb_cmd ("Confirm cancellation",
+ READER_CANCELLED,
+ NULL);
+ cmd_deny_vend = setup_mdb_cmd ("Deny Vend",
+ READER_VEND_DENIED,
+ NULL);
endSession = setup_mdb_cmd ("End Session",
READER_END_SESSION,
NULL);
- revalueApproved = setup_mdb_cmd ("Reader Approve Revalue",
- READER_REVALUE_APPROVED,
- NULL);
+ cmd_revalue_approved = setup_mdb_cmd ("Reader Approve Revalue",
+ READER_REVALUE_APPROVED,
+ NULL);
- revalueAmount = setup_mdb_cmd ("Send Revalue Limit Amount",
- READER_REVALUE_LIMIT,
- READER_REVALUE_LIMIT_AMOUNT);
+ cmd_revalue_amount = setup_mdb_cmd ("Send Revalue Limit Amount",
+ READER_REVALUE_LIMIT,
+ READER_REVALUE_LIMIT_AMOUNT);
+
+ cmd_reader_NACK = setup_mdb_cmd ("Reader NACK",
+ READER_NACK,
+ NULL);
+ cmd_reader_display_sold_out = setup_mdb_cmd ("Display Sold Out",
+ READER_DISPLAY_REQUEST,
+ READER_DISPLAY_REQUEST_TIME
+ READER_DISPLAY_SOLD_OUT);
+
+ cmd_reader_display_internal_error = setup_mdb_cmd (
+ "Display Communication Error",
+ READER_DISPLAY_REQUEST,
+ READER_DISPLAY_REQUEST_TIME
+ READER_DISPLAY_INTERNAL_ERROR);
+
+ cmd_reader_display_backend_not_reachable = setup_mdb_cmd (
+ "Display Backend not reachable",
+ READER_DISPLAY_REQUEST,
+ READER_DISPLAY_REQUEST_TIME
+ READER_DISPLAY_BACKEND_NOT_REACHABLE);
ret = GNUNET_PROGRAM_run (argc,
argv,
"taler-mdb",
diff --git a/taler.conf b/taler.conf
index 8f382dd..7d925de 100644
--- a/taler.conf
+++ b/taler.conf
@@ -1,9 +1,9 @@
[taler]
-currency = TESTKUDOS
+currency = EUR
[taler-mdb]
-backend-base-url = http://backend.test.taler.net/
-backend-authorization = ApiKey sandbox
+backend-base-url = http://backend.euro.taler.net/
+backend-authorization = ApiKey Sandbox
# taler url for success message (see taler documentation)
fulfillment-url = taler://fulfillment-success
# alternative url (see taler documentation)
@@ -22,149 +22,149 @@ FRAMEBUFFER_DEVICE = /dev/fb1
FRAMEBUFFER_BACKLIGHT = /sys/class/backlight/soc:backlight/brightness
#Products
+#If sold out is enabled, products with description "empty" will be registered as sold out.
#machine number 55
[product-21]
description = empty
-price = TESTKUDOS:0.1
+price = EUR:0.0
number = 46
#machine number 54
[product-20]
description = empty
-price = TESTKUDOS:0.1
+price = EUR:0.0
number = 45
#machine number 53
[product-19]
-description = empty
-price = TESTKUDOS:0.1
+description = Hackerspace Passport
+price = EUR:1.0
number = 44
#machine number 52
[product-18]
-description = empty
-price = TESTKUDOS:0.1
+description = T-Shirt M
+price = EUR:5.0
number = 43
#machine number 51
[product-17]
-description = empty
-price = TESTKUDOS:0.1
+description = T-Shirt S
+price = EUR:5.0
number = 42
#machine number 50
[product-16]
-description = empty
-price = TESTKUDOS:0.1
+description = Electronic Kit
+price = EUR:10.0
number = 41
#machine number 45
[product-15]
description = Snickers
-price = TESTKUDOS:0.1
+price = EUR:0.3
number = 36
#machine number 44
[product-14]
-description = empty
-price = TESTKUDOS:0.1
+description = Electronic Kit
+price = EUR:7.0
number = 35
#machine number 43
[product-13]
-description = Twix
-price = TESTKUDOS:0.1
+description = empty
+price = EUR:0.0
key = d
number = 34
#machine number 42
[product-12]
description = Screwdriver
-price = TESTKUDOS:0.1
+price = EUR:15.0
key = h
number = 33
#machine number 41
[product-11]
-description = empty
-price = TESTKUDOS:0.1
+description = Twix
+price = EUR:0.3
key = j
number = 32
#machine number 40
[product-10]
description = Mars
-price = TESTKUDOS:0.1
+price = EUR:0.3
key = k
-number = 30
+number = 31
#machine number 34
[product-9]
-description = empty
-price = TESTKUDOS:0.1
+description = Book GRM - Brainfuck
+price = EUR:25.0
key = l
number = 25
#machine number 30
[product-8]
-description = Meter
-price = TESTKUDOS:0.1
+description = Ruler
+price = EUR:10.0
key = w
number = 21
#machine number 25
[product-7]
-description = empty
-price = TESTKUDOS:0.1
+description = NFC TAG
+price = EUR:1.0
key = e
number = 16
#machine number 24
[product-6]
description = Knive
-price = TESTKUDOS:0.1
+price = EUR:25.0
key = r
number = 15
#machine number 23
[product-5]
-description = empty
-price = TESTKUDOS:0.1
+description = Electronic Kit
+price = EUR:5.0
key = t
number = 14
#machine number 22
[product-4]
description = empty
-price = TESTKUDOS:0.1
+price = EUR:0.0
key = z
number = 13
#machine number 21
[product-3]
description = empty
-price = TESTKUDOS:0.1
+price = EUR:0.0
key = u
number = 12
#machine number 20
[product-2]
description = Gummy bears
-price = TESTKUDOS:0.1
+price = EUR:0.3
key = i
-number = 10
+number = 11
#machine number 14
-[produt-1]
+[product-1]
description = Sword
-price = TESTKUDOS:0.1
-key = o
-number = 5
+price = EUR:0.05
+number = 5
#machine number 10
[product-0]
description = Umbrella
-price = TESTKUDOS:0.1
+price = EUR:10.0
key = p
number = 1