diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-01-24 12:27:54 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-01-24 12:36:05 +0100 |
commit | 09cf0428c632ad6698315b78b2f6a4db69c1d4a8 (patch) | |
tree | 7c1a48361328067ae439ad5c6ac38bd3195dba72 | |
parent | 237dbf9290ab2198894a703149eb1a5e2347da73 (diff) | |
parent | 1e464cbc9e230895ad3cee64f83bc4452b12e767 (diff) | |
download | taler-mdb-09cf0428c632ad6698315b78b2f6a4db69c1d4a8.tar.gz taler-mdb-09cf0428c632ad6698315b78b2f6a4db69c1d4a8.tar.bz2 taler-mdb-09cf0428c632ad6698315b78b2f6a4db69c1d4a8.zip |
fix style issues
-rw-r--r-- | src/main.c | 486 | ||||
-rw-r--r-- | taler.conf | 82 |
2 files changed, 408 insertions, 160 deletions
@@ -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", @@ -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 |