[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-mdb] 24/93: use event loop
From: |
gnunet |
Subject: |
[taler-taler-mdb] 24/93: use event loop |
Date: |
Mon, 18 Nov 2019 21:12:47 +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.
commit ca815f5c4cca08d5b1a2b259914db67bbf9e5e2e
Author: Christian Grothoff <address@hidden>
AuthorDate: Sat Nov 9 11:51:02 2019 +0100
use event loop
---
src/Makefile.am | 5 +-
src/communication.c | 145 -----------
src/configuration.h | 20 --
src/main.c | 725 +++++++++++++++++++++++++++++++++++++++-------------
src/nfc.c | 100 --------
src/product.c | 122 ---------
src/product.h | 10 -
src/wallet.c | 82 ------
8 files changed, 552 insertions(+), 657 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 9e157b4..f8c0fe1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,14 +7,11 @@ if USE_COVERAGE
endif
taler_nfc_SOURCES = \
- nfc.c nfc.h \
- wallet.c wallet.h \
- product.c product.h \
- communication.c communication.h \
main.c
taler_nfc_LDADD = \
-ltalermerchant \
-ltalerutil \
+ -lgnunetcurl \
-lgnunetutil \
-ljansson \
-lnfc \
diff --git a/src/communication.c b/src/communication.c
index 7f51388..b9110db 100644
--- a/src/communication.c
+++ b/src/communication.c
@@ -33,151 +33,6 @@ along with
#include "wallet.h"
#include "configuration.h"
-int SNACK_taler_init (CURL **curl)
-{
- CURLcode result;
-
- /* initialize curl */
- result = curl_global_init (CURL_GLOBAL_ALL);
- *curl = curl_easy_init ();
- if ( ! (*curl) ||(result != CURLE_OK))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_taler_init: could not inizialize curl handle\n");
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
-void SNACK_taler_exit (CURL **curl)
-{
- curl_easy_cleanup (*curl);
- curl_global_cleanup ();
-}
-
-static size_t _SNACK_taler_write_response (void *contents, size_t size, size_t
- nmemb,
- void *userp)
-{
- size_t realSize = size * nmemb;
- struct TalerResponse *response = (struct TalerResponse *) userp;
-
- response->string = GNUNET_realloc (response->string, response->size
- + realSize + 1);
-
- memcpy (&(response->string[response->size]), contents, realSize);
- response->size += realSize;
- response->string[response->size] = 0;
-
- return realSize;
-}
-
-int SNACK_taler_create_order_req (ProductOrder *product)
-{
- json_t *orderReq;
-
- /* create the string representing the amount, e.g. "KUDOS:2.5" ( +2 because
of ':' and '\0' ) */
- char amountStr[ strlen (product->talerCfg->currency) + strlen (
- product->amount) + 2 ];
- /* create the fulfillment ur, e.g.
"taler://fulfillment-success/Enjoy+your+ice+cream!"; ( +2 because of '!' and
'\0' ) */
- char fulfillmentUrl[ strlen (product->talerCfg->fulfillmentUrl) + strlen (
- product->talerCfg->fulfillmentMsg)
- + strlen (product->product) + 2 ];
-
- /* create the strings declared earlier */
- sprintf (amountStr, "%s:%s", product->talerCfg->currency, product->amount);
- sprintf (fulfillmentUrl, "%s%s%s!", product->talerCfg->fulfillmentUrl,
- product->talerCfg->fulfillmentMsg,
- product->product);
-
- /* create the json object for the order request */
- orderReq = json_pack ("{ s: { s:s, s:s, s:s, s:s }}", SNACK_JSON_REQ_ORDER,
- SNACK_JSON_REQ_SUMMARY, product->product,
- SNACK_JSON_REQ_AMOUNT, amountStr,
- SNACK_JSON_REQ_FULFILLMENT, fulfillmentUrl,
- SNACK_JSON_REQ_NONCE, product->nonce);
- if ( ! orderReq )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_taler_create_order_req: error creating json object\n");
- return EXIT_FAILURE;
- }
-
- /* create the string to send to taler in compact format */
- char *buffer = json_dumps (orderReq, JSON_COMPACT);
- if ( ! buffer )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_taler_create_order_req: error converting json to
string\n");
- return EXIT_FAILURE;
- }
-
- /* allocate memory for the string and copy it into the product */
- product->orderRequest = GNUNET_realloc (product->orderRequest, strlen (
- buffer) + 1);
- strcpy (product->orderRequest, buffer);
-
- /* print the created order request and free the json object */
- printf ("Created order Request: \n");
- json_dumpf (orderReq, stdout, JSON_INDENT (2) );
- printf ("\n");
- json_decref (orderReq);
-
- /* free the allocated buffer from json_dumps */
- free (buffer);
-
- return EXIT_SUCCESS;
-}
-
-int SNACK_taler_create_order (CURL *curl, ProductOrder *product)
-{
- CURLcode result;
- struct curl_slist *list = NULL;
- char url[ strlen (product->talerCfg->backendBaseUrl) + strlen (
- SNACK_TALER_ORDER) + 1 ];
-
- /* reset the response size */
- product->response->size = 0;
-
- /* set the url */
- sprintf (url, "%s%s", product->talerCfg->backendBaseUrl, SNACK_TALER_ORDER);
- curl_easy_setopt (curl, CURLOPT_URL, url);
-
- /* set the authentication headers */
- list = curl_slist_append (list, product->talerCfg->authorization);
- curl_easy_setopt (curl, CURLOPT_HTTPHEADER, list);
-
- /* curl option "post" */
- curl_easy_setopt (curl, CURLOPT_HTTPPOST, true);
- curl_easy_setopt (curl, CURLOPT_POSTFIELDS, product->orderRequest);
-
- /* pass the write function and the struct to write to */
- curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, _SNACK_taler_write_response);
- curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *) product->response);
-
- /* perform the call */
- result = curl_easy_perform (curl);
- if ( result != CURLE_OK )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_taler_create_order: could not communicate with
\"%s\"\n",
- url);
- curl_slist_free_all (list);
- return EXIT_FAILURE;
- }
-
- /* reset the curl options */
- curl_easy_reset (curl);
-
- /* clean up */
- curl_slist_free_all (list);
-
-
- printf ("%s\n", product->response->string);
-
- return EXIT_SUCCESS;
-}
int SNACK_taler_check_payment_status (CURL *curl, ProductOrder *product)
{
diff --git a/src/configuration.h b/src/configuration.h
index 26a52b2..86eb7e5 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -42,41 +42,21 @@ along with
#define FULLFILLMENT_URL "fulfillment-url"
#define FULLFILLMENT_MSG "fulfillment-msg"
-/* default config file */
-#define SNACK_DEFAULT_CONFIG_FILE "taler-mdb.conf"
/* taler url extensions */
#define SNACK_TALER_ORDER "/order"
#define SNACK_TALER_CHECK "/check-payment"
#define SNACK_TALER_ORDER_CHECK "?order_id="
-/* curl auth header */
-#define SNACK_CURL_AUTH_HEADER "Authorization"
/* json order check keys */
#define SNACK_JSON_PAID "paid"
#define SNACK_JSON_PAY_URI "taler_pay_uri"
#define SNACK_JSON_ORDER_ID "order_id"
-/* json order request keys */
-#define SNACK_JSON_REQ_ORDER "order"
-#define SNACK_JSON_REQ_SUMMARY "summary"
-#define SNACK_JSON_REQ_AMOUNT "amount"
-#define SNACK_JSON_REQ_FULFILLMENT "fulfillment_url"
-#define SNACK_JSON_REQ_NONCE "nonce"
/* nonce definitions */
#define NONCE_SIZE 32
-/* Wallet AID */
-static const uint8_t taler_aid[] = { 0xF0, 0x00, 0x54, 0x41, 0x4c, 0x45, 0x52
};
-
-/* APDU commands */
-#define APDU_SUCCESS "\x90\x00"
-static const uint8_t select_file[] = { 0x00, 0xA4, 0x04, 0x00, 0x07 };
-static const uint8_t put_data[] = { 0x00, 0xDA, 0x01, 0x00, 0x7c, 0x01 };
-
-/* tunneling */
-static const uint8_t get_data[] = { 0x00, 0xCA, 0x01, 0x00, 0x00, 0x00 };
#endif // URL_H
diff --git a/src/main.c b/src/main.c
index e55d2b3..ff4c350 100644
--- a/src/main.c
+++ b/src/main.c
@@ -33,79 +33,164 @@ along with
#include <gnunet/gnunet_util_lib.h>
#include <taler/taler_merchant_service.h>
-#include "nfc.h"
-#include "communication.h"
-#include "configuration.h"
-#include "product.h"
+#define BACKEND_POLL_TIMEOUT GNUNET_TIME_UNIT_MINUTES
-static int global_ret;
+#define APDU_SUCCESS "\x90\x00"
-static struct GNUNET_SCHEDULER_Task *super_task;
+/* json order request keys */
+#define SNACK_JSON_REQ_ORDER "order"
+#define SNACK_JSON_REQ_SUMMARY "summary"
+#define SNACK_JSON_REQ_AMOUNT "amount"
+#define SNACK_JSON_REQ_FULFILLMENT "fulfillment_url"
-static struct GNUNET_CURL_Context *ctx;
+/* default config file */
+#define SNACK_DEFAULT_CONFIG_FILE "taler-mdb.conf"
+
+/* curl auth header */
+#define SNACK_CURL_AUTH_HEADER "Authorization"
+
+
+/* Wallet AID */
+static const uint8_t taler_aid[] = { 0xF0, 0x00, 0x54, 0x41, 0x4c, 0x45, 0x52
};
+
+/* APDU commands */
+static const uint8_t select_file[] = { 0x00, 0xA4, 0x04, 0x00, 0x07 };
+static const uint8_t put_data[] = { 0x00, 0xDA, 0x01, 0x00, 0x7c, 0x01 };
+
+/* tunneling */
+static const uint8_t get_data[] = { 0x00, 0xCA, 0x01, 0x00, 0x00, 0x00 };
-static struct GNUNET_CURL_RescheduleContext *;
+
+struct Product
+{
+ const char *price;
+ const char *description;
+ char key;
+};
struct PaymentActivity
{
- ProductOrder product;
struct TALER_MERCHANT_PollPaymentOperation *ppo;
struct TALER_MERCHANT_ProposalOperation *po;
+ struct TALER_MERCHANT_CheckPaymentOperation *cpo;
+
+ char *taler_pay_uri;
+
nfc_device *pnd;
+
+ nfc_target nt;
+
+ struct GNUNET_SCHEDULER_Task *task;
};
-nfc_context *context;
+static nfc_context *context;
+
+static int global_ret;
+
+static struct GNUNET_SCHEDULER_Task *keyboard_task;
+
+static struct GNUNET_CURL_Context *ctx;
+
+static struct GNUNET_CURL_RescheduleContext *rc;
+
+static char *currency;
+
+static char *backendBaseUrl;
+
+static char *fulfillmentUrl;
+
+static char *fulfillmentMsg;
+
+static char *authorization;
static struct PaymentActivity *payment_activity;
-static void *
-start_nfc_transmission (void *ignored)
-{
- /* supress warning about unused variable */
- (void) ignored;
- if (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) != 0)
+/**
+ * FIXME: read from configuration file instead!
+ * GNUNET_CONFIGURATION_* iteration over values.
+ */
+static struct Product products[] = {
+ {
+ .price = "0.1",
+ .description = "Snickers",
+ .key = 's'
+ },
{
- printf ("Error setting thread cancelling type\n");
+ .price = "0.1",
+ .description = "Twix",
+ .key = 't'
+ },
+ {
+ .price = NULL,
+ .description = NULL,
+ .key = '\0'
}
+};
- /* start endless transmission loop (until threads gets cancelled) */
- while (1)
- {
- if ( pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL) != 0 )
- {
- printf ("Error setting thread cancelling state\n");
- }
- SNACK_nfc_transmit (context, product.payUrl, strlen (product.payUrl) );
- if ( pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0)
- {
- printf ("Error setting thread cancelling state\n");
- }
- sleep (1);
+
+static void
+SNACK_print_hex_info (const char*message,
+ const uint8_t *hexArray,
+ size_t sizeHex)
+{
+ char hex[5] = {""};
+ char str[64] = {""};
+
+ for ( unsigned int i = 0; i < sizeHex; ++i ) {
+ sprintf (hex, "%.2x ", hexArray[i]);
+ strcat (str, hex);
}
- return EXIT_SUCCESS;
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "%s: %s\n", message, str);
+
}
+static void
+cleanup_payment (struct PaymentActivity *pa)
+{
+ if (NULL != pa->po)
+ TALER_MERCHANT_proposal_cancel (pa->po);
+ if (NULL != pa->ppo)
+ TALER_MERCHANT_poll_payment_cancel (pa->ppo);
+ if (NULL != pa->cpo)
+ TALER_MERCHANT_check_payment_cancel (pa->cpo);
+ if (NULL != pa->task)
+ GNUNET_SCHEDULER_cancel (pa->task);
+ if (NULL != pa->pnd)
+ {
+ nfc_initiator_deselect_target (pa->pnd); // needed?
+ nfc_close (pa->pnd);
+ }
+ GNUNET_free_non_null (pa->taler_pay_uri);
+ GNUNET_free (pa);
+}
+
static void
shutdown_task (void *cls)
{
(void) cls;
- /* clear all initialized data */
if (NULL != context)
+ {
nfc_exit (context);
- if (NULL != product)
- SNACK_product_exit (&product);
- if (NULL != curl)
- SNACK_taler_exit (&curl);
- if (NULL != super_task)
- GNUNET_SCHEDULER_cancel (super_task);
+ context = NULL;
+ }
+ if (NULL != payment_activity)
+ {
+ cleanup_payment (payment_activity);
+ payment_activity = NULL;
+ }
+ if (NULL != keyboard_task)
+ {
+ GNUNET_SCHEDULER_cancel (keyboard_task);
+ keyboard_task = NULL;
+ }
if (NULL != ctx)
{
GNUNET_CURL_fini (ctx);
@@ -119,101 +204,244 @@ shutdown_task (void *cls)
}
+/**
+ * Callback to process a GET /poll-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
-run (void *cls,
- char *const *args,
- const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+poll_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)
{
- /* inizialize product */
- if ( SNACK_product_init (&product, cfg) )
+ struct PaymentActivity *pa = cls;
+
+ pa->ppo = NULL;
+ // FIXME: handle different http_status codes more nicely
+ if (paid)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "main: unable to init product structure\n");
- global_ret = EXIT_FAILURE;
- return;
+ fprintf (stderr,
+ "FIXME: yield product here!\n");
+ cleanup_payment (pa);
+ GNUNET_assert (payment_activity == pa);
+ payment_activity = NULL;
}
- GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
- NULL);
- /* initialize nfc */
- nfc_init (&context);
- if ( ! context )
+ else
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "main: unable to init nfc\n");
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
+ cleanup_payment (pa);
+ GNUNET_assert (payment_activity == pa);
+ payment_activity = NULL;
}
+}
+
+
+static void
+connect_target (void *cls);
- /* inizialize taler */
- if ( SNACK_taler_init (&curl) )
+
+static void
+wallet_select_aid (void *cls);
+
+
+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->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 to wallet\n");
+ if (nfc_initiator_transceive_bytes (pa->pnd,
+ message,
+ sizeof (message),
+ response,
+ sizeof(response),
+ 1 /* timeout, 1 ms */) < 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "main: nable to init taler communication\n");
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
+ "SNACK_wallet_put_message: Failed to put message\n");
+ pa->task = GNUNET_SCHEDULER_add_delayed (
+ GNUNET_TIME_UNIT_SECONDS /* FIXME: timeout? */,
+ &wallet_select_aid, /* TBD: where to resume? */
+ pa);
return;
}
- ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
- &is.rc);
- rc = GNUNET_CURL_gnunet_rc_create (ctx);
- start_read_keyboard ();
+ pa->task = GNUNET_SCHEDULER_add_delayed (
+ GNUNET_TIME_UNIT_SECONDS /* FIXME: timeout? */,
+ &wallet_transmit_uri, /* TBD: where to resume? */
+ pa);
}
static void
-start_read_keyboard ()
+wallet_select_aid (void *cls)
{
- struct GNUNET_DISK_FileHandle fh = { FILENO_STDIN };
-
- printf ("Waiting for MBD input\n");
- printf ("Enter to simulate Snickers, x to quit\n");
- super_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_ABS,
- fh,
- &read_product_info,
- NULL);
+ 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));
+
+ if (nfc_initiator_transceive_bytes (pa->pnd,
+ message,
+ sizeof (message),
+ response,
+ sizeof(response),
+ 1 /* timeout in ms */) < 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "nfc_initiator_transceive_bytes: Failed to select apk\n");
+ pa->task = GNUNET_SCHEDULER_add_delayed (
+ GNUNET_TIME_UNIT_SECONDS /* FIXME: timeout? */,
+ &wallet_select_aid, /* TBD: where
to resume? */
+ pa);
+ return;
+ }
+ if (0 == memcmp (response,
+ APDU_SUCCESS,
+ sizeof (response)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Taler wallet found\n");
+ pa->task = GNUNET_SCHEDULER_add_now (&wallet_transmit_uri,
+ pa);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "AID selection failure, return code: %x%x\n",
+ response[0],
+ response[1]);
+ pa->task = GNUNET_SCHEDULER_add_delayed (
+ GNUNET_TIME_UNIT_SECONDS /* FIXME: timeout? */,
+ &wallet_select_aid, /* TBD: where to resume? */
+ pa);
}
+
+/* upper and lower bounds for mifare targets uid length */
+#define UID_LEN_UPPER 7
+#define UID_LEN_LOWER 4
+
+
static void
-read_product_info (void *cls)
+connect_target (void *cls)
{
- int input;
-
- super_task = NULL;
- input = getchar ();
- if ( (EOF == input) ||
- ('x' == (char) input) )
+ struct PaymentActivity *pa = cls;
+ const nfc_modulation nmMifare[] = { {
+ .nmt = NMT_ISO14443A,
+ .nbr = NBR_106,
+ } };
+
+ pa->task = NULL;
+ pa->nt.nti.nai.szUidLen = 0;
+ if (nfc_initiator_select_passive_target (pa->pnd,
+ nmMifare[0], NULL, 0, &pa->nt) <=
+ 0 )
{
- GNUNET_SCHEDULER_shutdown ();
- return;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "SNACK_nfc_connect_target: failed to connect\n");
}
- switch ((char) input)
+ else if ( (pa->nt.nti.nai.szUidLen > UID_LEN_UPPER) ||
+ (pa->nt.nti.nai.szUidLen < UID_LEN_LOWER) )
{
- case 'c':
- if (NULL != payment_activity)
- {
- cancel_payment (payment_activity);
- payment_activity = NULL;
- }
- break;
- case 's':
- GNUNET_assert (NULL == payment_activity);
- product.amount = "0.1";
- product.product = "Snickers";
- payment_activity = launch_payment (&product);
- break;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "SNACK_nfc_connect_target: failed to connect\n");
+ SNACK_print_hex_info ("UID",
+ pa->nt.nti.nai.abtUid,
+ pa->nt.nti.nai.szUidLen);
}
- start_read_keyboard ();
+ else
+ {
+ pa->task = GNUNET_SCHEDULER_add_now (&wallet_select_aid,
+ pa);
+ return;
+ }
+ nfc_initiator_deselect_target (pa->pnd);
+ pa->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ &connect_target,
+ pa);
}
+/**
+ * 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
-cancel_payment (struct PaymentActivity *pa)
+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)
{
- if (NULL != pa->po)
- TALER_MERCHANT_proposal_cancel (pa->po);
- GNUNET_free (pa);
+ struct PaymentActivity *pa = cls;
+
+ pa->cpo = NULL;
+ // FIXME: check http_status, yada yada
+ pa->taler_pay_uri = GNUNET_strdup (taler_pay_uri);
+ pa->pnd = nfc_open (context, NULL);
+ if (NULL != pa->pnd)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Payment inititation: Unable to open nfc device\n");
+ cleanup_payment (pa);
+ GNUNET_assert (payment_activity == pa);
+ payment_activity = NULL;
+ return;
+ }
+ if (0 > nfc_initiator_init (pa->pnd))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to initialize NFC device: %s",
+ 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);
}
@@ -227,111 +455,260 @@ proposal_cb (void *cls,
struct PaymentActivity *pa = cls;
pa->po = NULL;
- // use(order_id);
- // start_nfc_transmission(pa);
- // pa->pnd = open();
- //
+ 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);
+ cleanup_payment (pa);
+ GNUNET_assert (payment_activity == pa);
+ payment_activity = NULL;
+ return;
+ }
+ pa->ppo = TALER_MERCHANT_poll_payment (ctx,
+ backendBaseUrl,
+ order_id,
+ NULL /* &FIXME_h_contract! */,
+ NULL /* snack machine, no Web crap */,
+ BACKEND_POLL_TIMEOUT,
+ &poll_payment_cb,
+ pa);
+ pa->cpo = TALER_MERCHANT_check_payment (ctx,
+ backendBaseUrl,
+ order_id,
+ NULL /* snack machine, no Web crap
*/,
+ &check_payment_cb,
+ pa);
+
}
static struct PaymentActivity *
-launch_payment (const Product *product)
+launch_payment (const struct Product *product)
{
struct PaymentActivity *pa;
-
+ json_t *orderReq;
+ char *amountStr;
+ char *fulfillmentUrl;
+
+ /* create the string representing the amount, e.g. "KUDOS:2.5" */
+ GNUNET_asprintf (&amountStr,
+ "%s:%s",
+ currency,
+ product->price);
+ /* create the fulfillment url, e.g.
"taler://fulfillment-success/Enjoy+your+ice+cream!"; */
+ GNUNET_asprintf (&fulfillmentUrl,
+ "%s%s%s!",
+ fulfillmentUrl,
+ fulfillmentMsg,
+ product->description);
+ /* create the json object for the order request */
+ orderReq = json_pack ("{ s:s, s:s, s:s }",
+ SNACK_JSON_REQ_SUMMARY, product->description,
+ SNACK_JSON_REQ_AMOUNT, amountStr,
+ SNACK_JSON_REQ_FULFILLMENT, fulfillmentUrl);
+ GNUNET_free (amountStr);
+ GNUNET_free (fulfillmentUrl);
+ if (NULL == orderReq)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "json_pack failed (out of memory?)\n");
+ return NULL;
+ }
pa = GNUNET_new (struct PaymentActivity);
- pa->product = *product;
- // SEE: SNACK_taler_create_order_req (&product);
- order = json ();
pa->po = TALER_MERCHANT_order_put (ctx,
- backend_url,
- order,
+ 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;
}
-static void foo ()
-{
- /* create the order request */
- SNACK_taler_create_order_req (&product);
-
- /* create the order */
- while ( SNACK_taler_create_order (curl, &product) )
- ;
- /* store the order id into the struct */
- SNACK_product_set_order_id (&product);
-
- /* store the url to check wheter the payment happened or not */
- SNACK_product_set_check_url (&product);
+static void
+start_read_keyboard (void);
- /* check the payment status for the first time */
- while ( SNACK_taler_check_payment_status (curl, &product) )
- ;
- /* store the url to pay, to do this task the payment status has to be called
before, because the url will be in the response */
- SNACK_product_set_pay_url (&product);
+static void
+read_keyboard_command (void *cls)
+{
+ int input;
- /* start a thread to send payment request to taler wallet */
- pthread_t nfcThread;
- if ( pthread_create (&nfcThread,
- NULL,
- &start_nfc_transmission,
- NULL) )
+ keyboard_task = NULL;
+ input = getchar ();
+ if ( (EOF == input) ||
+ ('x' == (char) input) )
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "main: thread creation failed\n");
- return EXIT_FAILURE;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
}
-
- /* check the payment status, if paid exit while loop and end thread
transmitting nfc messages */
- while ( ! product.paid )
+ if ((char) input == 'c')
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "main: order payment processing\n");
- sleep (5);
-
- while ( SNACK_taler_check_payment_status (curl, &product) )
- ;
-
- /* set the boolean paid member of ProductOrder struct */
- SNACK_product_set_paid_status (&product);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "main: payment status paid: %s\n",
- (product.paid ? "true" : "false") );
+ if (NULL != payment_activity)
+ {
+ cleanup_payment (payment_activity);
+ payment_activity = NULL;
+ }
+ else
+ {
+ fprintf (stderr,
+ "No purchase activity pending\n");
+ }
+ start_read_keyboard ();
+ return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "main: order no.: %s paid!\n",
- product.orderID);
+ if (NULL == payment_activity)
+ {
+ fprintf (stderr,
+ "Purchase activity already pending\n");
+ start_read_keyboard ();
+ return;
+ }
+ for (unsigned int i = 0; NULL != products[i].price; 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 ();
+}
- /* -----------------
- Here comes the code for releasing the product
- ----------------- */
+static void
+start_read_keyboard ()
+{
+ struct GNUNET_DISK_FileHandle fh = { STDIN_FILENO };
+
+ GNUNET_assert (NULL == keyboard_task);
+ printf ("c' to cancel last purchase, 'x' to quit\n");
+ for (unsigned int i = 0; NULL != products[i].price; i++)
+ printf ("'%c' to buy %s\n",
+ products[i].key,
+ products[i].description);
+ printf ("Waiting for keyboard input\n");
+ keyboard_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ &fh,
+ &read_keyboard_command,
+ NULL);
+}
- /* send cancel request to nfc thread */
- while ( pthread_cancel (nfcThread) != 0 )
+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",
+ ¤cy))
{
- printf ("Error sending cancel request to thread for nfc transmission");
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "taler",
+ "currency");
+ global_ret = EXIT_FAILURE;
+ return;
}
-
- void*res;
- if ( pthread_join (nfcThread, &res) == 0 )
+ 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",
+ SNACK_CURL_AUTH_HEADER,
+ auth);
+ GNUNET_free (auth);
+ }
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ "taler-mdb",
+ "fulfillment-url",
+ &fulfillmentUrl))
{
- printf ("Thread for nfc transmission finished\n");
- fflush (stdout);
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "taler-mdb",
+ "fulfillment-url");
+ global_ret = EXIT_FAILURE;
+ return;
}
- else if ( res == PTHREAD_CANCELED )
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ "taler-mdb",
+ "fulfillment-msg",
+ &fulfillmentMsg))
{
- printf ("Thread for nfc transmission finished\n");
- fflush (stdout);
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "taler-mdb",
+ "fulfillment-msgcurrency");
+ global_ret = EXIT_FAILURE;
+ return;
}
- /* reset the product */
- SNACK_product_reset (&product);
+ GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+ NULL);
+ /* 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));
+ start_read_keyboard ();
}
-
int
main (int argc,
char*const*argv)
@@ -345,7 +722,7 @@ main (int argc,
GNUNET_PROGRAM_run (argc,
argv,
"taler-mdb",
- "This is an application for snack machines to pay
with GNU Taler via nfc.\n"
+ "This is an application for snack machines to pay
with GNU Taler via nfc.\n",
options,
&run,
NULL))
diff --git a/src/nfc.c b/src/nfc.c
index 52fc153..3c692b1 100644
--- a/src/nfc.c
+++ b/src/nfc.c
@@ -30,103 +30,3 @@ along with
#include "nfc.h"
#include "wallet.h"
-
-
-/* upper and lower bounds for mifare targets uid length */
-#define UID_LEN_UPPER 7
-#define UID_LEN_LOWER 4
-
-
-int SNACK_nfc_transmit (nfc_context *context, const char *talerPayUrl, size_t
- urlSize)
-{
- nfc_device *pnd;
- nfc_target nt;
-
- pnd = nfc_open (context, NULL);
- if ( ! pnd )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_nfc_transmit: Unable to open nfc device\n");
- return EXIT_FAILURE;
- }
-
- /* initialize device as reader */
- if ( nfc_initiator_init (pnd) < 0 )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Snack_nfc_transmit: nfc_initator_init error: %s",
- nfc_strerror (pnd) );
- nfc_close (pnd);
- return EXIT_FAILURE;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "SNACK_nfc_transmit: device: %s\n",
- nfc_device_get_name (pnd));
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "SNACK_nfc_transmit: connstring: %s\n",
- nfc_device_get_connstring (pnd));
-
- /* connect to a target device */
- if ( SNACK_nfc_connect_target (pnd, &nt) )
- {
- nfc_close (pnd);
- return EXIT_FAILURE;
- }
-
- /* send the message to the wallet */
- if ( SNACK_wallet_transmit (pnd, talerPayUrl, urlSize) )
- {
- /* the transmition failed, the target has to be reselected when using
MIFARE as defined in libnfc --> exit */
- nfc_close (pnd);
- return EXIT_FAILURE;
- }
-
- /* clean up */
- nfc_initiator_deselect_target (pnd);
- nfc_close (pnd);
-
- return EXIT_SUCCESS;
-}
-
-int SNACK_nfc_connect_target (nfc_device *pnd, nfc_target *nt)
-{
- /* ctr for how many tries to connect a target */
- int ctr = 2;
-
- const nfc_modulation nmMifare[] = { {
- .nmt = NMT_ISO14443A,
- .nbr = NBR_106,
- } };
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "SNACK_nfc_connect_target: trying to connect to target\n");
-
- while ( ctr > 0 )
- {
- /* set uid length to zero ( in case of second selecting the length still
has the old value ) */
- nt->nti.nai.szUidLen = 0;
- if ( nfc_initiator_select_passive_target (pnd, nmMifare[0], NULL, 0, nt) <=
- 0 )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_nfc_connect_target: failed to connect\n");
- }
- else if ((nt->nti.nai.szUidLen > UID_LEN_UPPER) ||(nt->nti.nai.szUidLen <
- UID_LEN_LOWER) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_nfc_connect_target: failed to connect\n");
- SNACK_print_hex_info ("UID", nt->nti.nai.abtUid, nt->nti.nai.szUidLen);
- }
- else {
- /*GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "SNACK_nfc_connect_target: Target selected!\n");
- SNACK_print_hex_info ("UID", nt->nti.nai.abtUid, nt->nti.nai.szUidLen);*/
- return EXIT_SUCCESS;
- }
- sleep (1);
- ctr--;
- }
-
- return EXIT_FAILURE;
-}
diff --git a/src/product.c b/src/product.c
index 2baae95..99fb583 100644
--- a/src/product.c
+++ b/src/product.c
@@ -32,95 +32,7 @@ the attributes.
#include "configuration.h"
#include "communication.h"
-void SNACK_product_reset (ProductOrder *product)
-{
- product->amount = NULL;
- product->product = NULL;
- product->paid = false;
-
- /* regenerate nonce */
- SNACK_product_generate_nonce (&(product->nonce), NONCE_SIZE);
-}
-
-int SNACK_product_init (ProductOrder *product, struct
- GNUNET_CONFIGURATION_Handle *cfg)
-{
- if ( ! product )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_product_init: product order struct must be provided\n");
- return EXIT_FAILURE;
- }
-
- /* allocate the taler config struct */
- product->talerCfg = GNUNET_malloc (sizeof(TalerConfig));
- /* get the configurable parameters and store them in the productOrder struct
*/
- if ( SNACK_product_set_cfg_value (cfg, TALER, CURRENCY,
- &product->talerCfg->currency))
- return EXIT_FAILURE;
- if ( SNACK_product_set_cfg_value (cfg, BACKOFFICE, BACKEND_BASE_URL,
- &product->talerCfg->backendBaseUrl))
- return EXIT_FAILURE;
- if ( SNACK_product_set_cfg_value (cfg, TALER, FULLFILLMENT_URL,
- &product->talerCfg->fulfillmentUrl))
- return EXIT_FAILURE;
- if ( SNACK_product_set_cfg_value (cfg, TALER, FULLFILLMENT_MSG,
- &product->talerCfg->fulfillmentMsg))
- return EXIT_FAILURE;
-
-
- /* create the Authorization: ..... option for curl */
- char*auth;
- if ( SNACK_product_set_cfg_value (cfg, BACKOFFICE, AUTHORIZATION, &auth))
- return EXIT_FAILURE;
- product->talerCfg->authorization = GNUNET_malloc (strlen (
- SNACK_CURL_AUTH_HEADER)
- + strlen (": ") + strlen (
- auth) + 1);
- sprintf (product->talerCfg->authorization, "%s: %s", SNACK_CURL_AUTH_HEADER,
- auth);
- GNUNET_free (auth);
-
-
- /* malloc for every string member with size 1, every other func just calls
- * realloc, because this struct gets used over and over again */
- product->response = GNUNET_malloc (sizeof(TalerResponse));
- product->response->string = GNUNET_malloc (1);
- product->orderID = GNUNET_malloc (1);
- product->payUrl = GNUNET_malloc (1);
- product->checkUrl = GNUNET_malloc (1);
- product->orderRequest = GNUNET_malloc (1);
- product->amount = NULL;
- product->product = NULL;
- product->paid = false;
-
- /* generate nonce */
- product->nonce = GNUNET_malloc (NONCE_SIZE);
- SNACK_product_generate_nonce (&(product->nonce), NONCE_SIZE);
-
- return EXIT_SUCCESS;
-}
-
-void SNACK_product_exit (ProductOrder *product)
-{
- GNUNET_free (product->response->string);
- GNUNET_free (product->response);
- GNUNET_free (product->nonce);
- GNUNET_free (product->orderID);
- GNUNET_free (product->orderRequest);
- GNUNET_free (product->payUrl);
- GNUNET_free (product->checkUrl);
- GNUNET_free (product->talerCfg->currency);
- GNUNET_free (product->talerCfg->authorization);
- GNUNET_free (product->talerCfg->backendBaseUrl);
- GNUNET_free (product->talerCfg->fulfillmentUrl);
- GNUNET_free (product->talerCfg->fulfillmentMsg);
- GNUNET_free (product->talerCfg);
- product->amount = NULL;
- product->product = NULL;
- product->paid = false;
-}
int SNACK_product_set_check_url (ProductOrder *product)
{
@@ -138,11 +50,6 @@ int SNACK_product_set_check_url (ProductOrder *product)
return EXIT_SUCCESS;
}
-int SNACK_product_set_order_id (ProductOrder *product)
-{
- return SNACK_taler_parse_json (product->response, SNACK_JSON_ORDER_ID,
- &(product->orderID));
-}
int SNACK_product_set_pay_url (ProductOrder *product)
{
@@ -192,32 +99,3 @@ int SNACK_product_set_paid_status (ProductOrder *product)
return EXIT_SUCCESS;
}
-
-
-int SNACK_product_set_cfg_value (struct GNUNET_CONFIGURATION_Handle *cfg, const
- char*section, const char *key, char **value)
-{
-
- if ( GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, section, key,
- value))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_product_set_cfg_value: no value '%s' or section '%s' in
config file found\n",
- key, section);
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
-void SNACK_product_generate_nonce (char**nonce, size_t size)
-{
- uint32_t temp;
- for ( size_t i = 0; i < size; ++i) {
- do temp = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 122);
- while ( (temp < '1' || temp > '9') & (temp < 'A' || temp > 'Z') & (temp <
- 'a' ||
- temp >
- 'z') );
- (*nonce)[i] = temp;
- }
-}
diff --git a/src/product.h b/src/product.h
index 44fbb72..7605cf6 100644
--- a/src/product.h
+++ b/src/product.h
@@ -40,15 +40,6 @@ typedef struct TalerResponse
size_t size;
} TalerResponse;
-typedef struct TalerConfig
-{
- char *currency;
- char *backendBaseUrl;
- char *fulfillmentUrl;
- char *fulfillmentMsg;
- char *authorization;
-} TalerConfig;
-
typedef struct ProductOrder
{
char *product;
@@ -59,7 +50,6 @@ typedef struct ProductOrder
char *payUrl;
char *orderRequest;
bool paid;
- TalerConfig *talerCfg;
TalerResponse *response;
} ProductOrder;
diff --git a/src/wallet.c b/src/wallet.c
index fc3c35e..1d7e8da 100644
--- a/src/wallet.c
+++ b/src/wallet.c
@@ -36,52 +36,10 @@ along with
int SNACK_wallet_select_aid (nfc_device *pnd)
{
- uint8_t response[] = { 0x00, 0x00 };
-
- int size = sizeof(select_file) + sizeof(taler_aid);
- uint8_t message[size];
- if ( SNACK_concat_message (select_file, sizeof(select_file), taler_aid,
- message,
- size) )
- return EXIT_FAILURE;
-
- /*
- SNACK_print_hex_info (
- "SNACK_wallet_select_aid: Selecting Taler apk using AID", taler_aid,
- sizeof(taler_aid));
- */
-
- if ( nfc_initiator_transceive_bytes (pnd, message, size, response,
- sizeof(response), TRANSMIT_TIMEOUT) < 0
)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_wallet_select_aid: Failed to select apk\n");
- return EXIT_FAILURE;
- }
-
- return SNACK_check_response (response, sizeof(response) );
}
int SNACK_put_message (nfc_device *pnd, const char *msg, size_t msgSize)
{
- uint8_t response[] = { 0x00, 0x00 };
- int size = sizeof(put_data) + msgSize;
- uint8_t message[size];
-
- if ( SNACK_concat_message (put_data, sizeof(put_data), (const uint8_t *) msg,
- message, size) )
- return EXIT_FAILURE;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "SNACK_wallet_put_messsage: Sending 'PUT DATA' command to
wallet\n");
-
- if ( nfc_initiator_transceive_bytes (pnd, message, size, response,
- sizeof(response), TRANSMIT_TIMEOUT) < 0
)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_wallet_put_message: Failed to put message\n");
- return EXIT_FAILURE;
- }
return SNACK_check_response (response, sizeof(response) );
}
@@ -110,32 +68,6 @@ int SNACK_wallet_tunneling (nfc_device *pnd, const char
*msg, size_t msgSize)
}
-int SNACK_wallet_transmit (nfc_device *pnd, const char *msg, size_t msgLen)
-{
- if ( ! msg )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "SNACK_wallet_transmit: No message to send\n");
- return EXIT_FAILURE;
- }
-
- if ( SNACK_wallet_select_aid (pnd) )
- return EXIT_FAILURE;
- if ( SNACK_put_message (pnd, msg, msgLen) )
- return EXIT_FAILURE;
-
- //
-------------------------------------------------------------------------------------------
- // sleep(3);
- // while ( SNACK_wallet_tunneling(pnd, msg, msgLen) == EXIT_SUCCESS )
- // sleep(3);
- // ;
- //
--------------------------------------------------------------------------------------------
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "SNACK_wallet_transmit: Transmitted message to taler wallet\n");
-
- return EXIT_SUCCESS;
-}
int SNACK_check_response (uint8_t *response, uint8_t responseLen)
{
@@ -173,17 +105,3 @@ int SNACK_concat_message (const uint8_t*command, size_t
commandSize, const
return EXIT_SUCCESS;
}
-
-void SNACK_print_hex_info (const char*message, const uint8_t *hexArray, size_t
- sizeHex)
-{
- char hex[5] = {""};
- char str[64] = {""};
-
- for ( unsigned int i = 0; i < sizeHex; ++i ) {
- sprintf (hex, "%.2x ", hexArray[i]);
- strcat (str, hex);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "%s: %s\n", message, str);
-
-}
--
To stop receiving notification emails like this one, please contact
address@hidden.
- [taler-taler-mdb] 17/93: merged jsonIntegrity, (continued)
- [taler-taler-mdb] 17/93: merged jsonIntegrity, gnunet, 2019/11/18
- [taler-taler-mdb] 23/93: chaos monkey, gnunet, 2019/11/18
- [taler-taler-mdb] 15/93: fixes, gnunet, 2019/11/18
- [taler-taler-mdb] 14/93: updated .gitignore, gnunet, 2019/11/18
- [taler-taler-mdb] 20/93: more implementations using GNUNETUtils, gnunet, 2019/11/18
- [taler-taler-mdb] 19/93: GNUnet logs added, -h option added, gnunet, 2019/11/18
- [taler-taler-mdb] 12/93: initial indenting, gnunet, 2019/11/18
- [taler-taler-mdb] 31/93: cleanup, gnunet, 2019/11/18
- [taler-taler-mdb] 33/93: typo, gnunet, 2019/11/18
- [taler-taler-mdb] 30/93: cleanup, gnunet, 2019/11/18
- [taler-taler-mdb] 24/93: use event loop,
gnunet <=
- [taler-taler-mdb] 32/93: retry NFC failures more nicely, gnunet, 2019/11/18
- [taler-taler-mdb] 36/93: fixed delay when cancelling, new bugs detected marked with FIXME, gnunet, 2019/11/18
- [taler-taler-mdb] 46/93: first steps in configurable products, gnunet, 2019/11/18
- [taler-taler-mdb] 28/93: misc cleanup, gnunet, 2019/11/18
- [taler-taler-mdb] 45/93: first steps in configurable products, gnunet, 2019/11/18
- [taler-taler-mdb] 40/93: fix, gnunet, 2019/11/18
- [taler-taler-mdb] 43/93: preparations for QR code alternative path, gnunet, 2019/11/18
- [taler-taler-mdb] 35/93: explicitly detect not-found code, gnunet, 2019/11/18
- [taler-taler-mdb] 39/93: use test for now, gnunet, 2019/11/18
- [taler-taler-mdb] 38/93: merged, gnunet, 2019/11/18