summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBOSS_Marco <bossm8@students.bfh.ch>2019-10-30 15:35:06 +0100
committerBOSS_Marco <bossm8@students.bfh.ch>2019-10-30 15:35:06 +0100
commit895f886cbe84c1b3cf1aa7583f30913e9ee052c4 (patch)
tree75aa5b955153dccbf73d888a8cbc5f682e2dac8d
downloadtaler-mdb-895f886cbe84c1b3cf1aa7583f30913e9ee052c4.tar.gz
taler-mdb-895f886cbe84c1b3cf1aa7583f30913e9ee052c4.tar.bz2
taler-mdb-895f886cbe84c1b3cf1aa7583f30913e9ee052c4.zip
initial commit
-rw-r--r--.gitignore12
-rw-r--r--README31
-rw-r--r--doc/.gitkeep0
-rw-r--r--src/configuration.h54
-rw-r--r--src/main.c166
-rw-r--r--src/makefile78
-rw-r--r--src/mdb/.gitkeep0
-rw-r--r--src/nfc-wallet/nfc.c118
-rw-r--r--src/nfc-wallet/nfc.h34
-rw-r--r--src/nfc-wallet/wallet.c124
-rw-r--r--src/nfc-wallet/wallet.h57
-rw-r--r--src/taler-processing/communication.c220
-rw-r--r--src/taler-processing/communication.h51
-rw-r--r--src/taler-processing/product.c126
-rw-r--r--src/taler-processing/product.h67
-rw-r--r--src/target.mk6
16 files changed, 1144 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a43af72
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+#ignore .pro fils
+*.pro*
+
+#ignore object files
+*.o
+
+#ignore build folder and binary files
+build
+taler-mdb
+
+#ignore qmake files
+.qmake*
diff --git a/README b/README
new file mode 100644
index 0000000..055745d
--- /dev/null
+++ b/README
@@ -0,0 +1,31 @@
+# Project : GNUTaler snack machine
+
+#### Author(s)
+ * BOSS Marco
+ * HOFER Dominik
+
+#### Prerequisite
+ * GNU gcc tool-chain
+ * C standard libraries
+ * libnfc
+ * libcurl
+ * pthread
+ * Gnu make
+
+#### Tested on
+ * Ubuntu LTS (18.04)
+
+#### Description
+ This is a app to run a snack machine as taler merchant with nfc payment interface.
+
+#### Tasks
+ * Add libjansson to parse and create json objects
+ * Build system, makefile provided is not suitable
+
+#### Remarks
+ * When using an ACR122 device there may be problems with libnfc, see libnfc for further information
+
+#### Noticeable points
+ * Taler wallet does not receive a second message when the payment was aborted, the wallet
+ has to be started again to receive a message via nfc
+ * Wallet does not show succes url string
diff --git a/doc/.gitkeep b/doc/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/doc/.gitkeep
diff --git a/src/configuration.h b/src/configuration.h
new file mode 100644
index 0000000..354e99e
--- /dev/null
+++ b/src/configuration.h
@@ -0,0 +1,54 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file configuration.h
+* @brief in this file you can set your url specifications needed to comminicate with taler
+* @author BOSS Marco
+*/
+
+#ifndef URL_H
+#define URL_H
+
+static const char* const ORDER = "/order";
+static const char* const CHECK = "/check-payment";
+static const char* const ORDER_CHECK = "?order_id=";
+
+static const char* const BACKEND_BASE_URL = "https://backend.demo.taler.net";
+
+static const char* const AUTH_HEADER = "Authorization: ApiKey sandbox";
+
+static const char* const JSON_PAID = "paid";
+static const char* const JSON_PAY_URI = "taler_pay_uri";
+static const char* const JSON_ORDER_ID = "order_id";
+
+
+
+//// will be replaced with libjansson functionalites -----------------------------------------------------------------------------------
+// ajust sprintf in taler_create_order_req communication.c if changed
+static const char* const JSON_ORDER = "{\n"
+ " \"order\":"
+ " {\n"
+ " \"summary\": \"%s\",\n"
+ " \"amount\": \"%s:%s\",\n"
+ " \"fulfillment_url\": \"taler://fulfillment-success/Enjoy+your+%s!\"\n"
+ " }\n"
+ "}";
+
+#endif // URL_H
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..504c2dd
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,166 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file main.c
+* @brief main functionality of the application
+* @author BOSS Marco
+* @author ...
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <nfc/nfc.h>
+#include <curl/curl.h>
+
+#include "nfc-wallet/nfc.h"
+#include "taler-processing/communication.h"
+#include "taler-processing/product.h"
+
+const char *CURRENCY = "KUDOS";
+
+
+ProductOrder product;
+nfc_context *context = NULL;
+
+
+void *start_nfc_transmission( void *ignored )
+{
+ // supress warning about unused variable
+ (void)ignored;
+
+ if( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL ) != 0 ){
+ printf( "Error setting thread cancelling type\n");
+ }
+ // 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" );
+ }
+ 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);
+ }
+ return EXIT_SUCCESS;
+}
+
+
+int main( )
+{
+ // initialize nfc
+ nfc_init( &context );
+ if( !context ){
+ printf( "Unable to init libnfc\n" );
+ return EXIT_FAILURE;
+ }
+
+ // inizialize taler
+ CURL *curl = NULL;
+ if( taler_init( &curl ) ){
+ printf( "Unable to init taler communication\n" );
+ return EXIT_FAILURE;
+ }
+
+ // inizialize product
+ if( product_init( &product, CURRENCY ) ){
+ printf( "Unable to init product\n" );
+ return EXIT_FAILURE;
+ }
+
+
+ while( true )
+ {
+ printf( "Waiting for MBD input\n" );
+ printf( "Enter to simulate Snickers, x to quit\n");
+ if( getchar() == 'x' )
+ break;
+
+ // DEMO snickers
+ product.amount = "0.1";
+ product.product = "Snickers";
+
+
+ // create the order request
+ taler_create_order_req( &product );
+
+ // create the order
+ while( taler_create_order( curl, &product ) );
+
+ // store the order id into the struct
+ product_set_order_id( &product );
+
+ // store the url to check wheter the payment happened or not
+ product_set_check_url( &product );
+
+ // check the payment status for the first time
+ while( 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
+ product_set_pay_url( &product );
+
+ // start a thread to send payment request to taler wallet
+ pthread_t nfcThread;
+ if( pthread_create(&nfcThread, NULL, start_nfc_transmission, NULL) ){
+ printf( "Could not create thread" );
+ return EXIT_FAILURE;
+ }
+
+ // check the payment status, if paid exit while loop and end thread transmitting nfc messages
+ while( !product.paid ){
+ printf( "Order payment processing\n" );
+ fflush(stdout);
+ sleep(5);
+ while( taler_check_payment_status( curl, &product ) );
+ // set the boolean paid member of ProductOrder struct
+ product_set_paid_status( &product );
+ printf( "Payment status paid: %s\n\n", (product.paid ? "true" : "false") );
+ }
+ printf( "Order no.: %s paid!\n\n", product.orderID );
+
+ // send cancel request to nfc thread
+ while( pthread_cancel(nfcThread) != 0 ){
+ printf( "Error sending cancel request to thread for nfc transmission" );
+ }
+ void*res;
+ if( pthread_join( nfcThread, &res ) == 0 ){
+ printf( "Thread for nfc transmission finished\n" );
+ fflush(stdout);
+ }else if( res == PTHREAD_CANCELED ){
+ printf( "Thread for nfc transmission finished\n" );
+ fflush(stdout);
+ }
+
+ // reset the product
+ product_reset( &product );
+
+ }
+
+ // clear all initialized data
+ nfc_exit( context );
+ product_exit( &product );
+ taler_exit( &curl );
+
+ return EXIT_SUCCESS;
+
+}
diff --git a/src/makefile b/src/makefile
new file mode 100644
index 0000000..792614d
--- /dev/null
+++ b/src/makefile
@@ -0,0 +1,78 @@
+include target.mk
+
+APP_NAME = taler-mdb
+
+SUBDIR_NFC=nfc-wallet
+SUBDIR_TAL=taler-processing
+
+CC = gcc
+
+# Compiler config
+CFLAGS += -Wall
+CFLAGS += -O1
+CFLAGS += -I ~/embedded/project/taler-mdb
+
+CROSS_CFLAGS += -Wall
+CROSS_CFLAGS += -O1
+CROSS_CFLAGS += -I ~/libnfc-1.7.0-rc7/include
+
+# Linker config
+LDFLAGS += -lnfc
+LDFLAGS += -lcurl
+LDFLAGS += -pthread
+
+CROSS_LDPATH += -L ~/embedded/x-tools/armv8-rpi3-linux-gnueabihf/lib/
+
+SOURCES=$(SUBDIR_NFC)/nfc.c $(SUBDIR_NFC)/wallet.c $(SUBDIR_TAL)/product.c $(SUBDIR_TAL)/communication.c main.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+CROSS_OBJECTS = $(SOURCES:.c=.o-$(TARGET_ARCH))
+
+SCP = scp
+SCPFLAGS =
+
+.PHONY: mrproper
+.PHONY: clean
+.PHONY: deploy
+.PHONY: target
+.PHONY: native
+
+
+all: target native
+
+native: $(APP_NAME)
+
+target: $(APP_NAME)-$(TARGET_ARCH)
+
+deploy: target
+ @echo "Copy $(TARGET_EXECUTABLE) to $(TARGET_ADDRESS)"
+ @$(SCP) $(SCPFLAGS) -o User $(TARGET_USER) -o HostName $(TARGET_ADDRESS) -P $(SSH_PORT) $(APP_NAME)-$(TARGET_ARCH)
+
+
+clean:
+ @find . -iname *.o -exec rm -f {} \;
+ @find . -iname *.o-* -exec rm -f {} \;
+
+mrproper: clean
+ @rm -f $(APP_NAME)-$(TARGET_ARCH)
+ @rm -f $(APP_NAME)
+ @find . -iname *~ -exec rm {} \;
+
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+libnfc-$(TARGET_ARCH) :
+
+
+$(SOURCES:.c=.o-$(TARGET_ARCH)): $(SOURCES)
+ $(CROSS_TOOLS)/$(CROSS)/bin/$(CROSS)-$(CC) $(CROSS_CFLAGS) -c $< -o $@
+
+
+$(APP_NAME)-$(TARGET_ARCH): $(CROSS_OBJECTS)
+ $(CROSS_TOOLS)/$(CROSS)/bin/$(CROSS)-$(CC) $(CROSS_LDPATH) $(LDFLAGS) -o $@ $?
+
+
+$(APP_NAME): $(OBJECTS)
+ $(CC) -o $@ $? $(LDFLAGS)
diff --git a/src/mdb/.gitkeep b/src/mdb/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/mdb/.gitkeep
diff --git a/src/nfc-wallet/nfc.c b/src/nfc-wallet/nfc.c
new file mode 100644
index 0000000..2b666f2
--- /dev/null
+++ b/src/nfc-wallet/nfc.c
@@ -0,0 +1,118 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file nfc.c
+* @brief functions used to comunicate over nfc interface
+* @author BOSS Marco
+*/
+
+#include <string.h>
+#include <unistd.h>
+
+#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 nfc_transmit( nfc_context *context, const char *talerPayUrl, size_t urlSize )
+{
+ nfc_device *pnd = NULL;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MEMORY LEAK? NFC OPEN?
+
+ pnd = nfc_open( context, NULL ); // NULL could be replaced with connstring if the correct is known
+ if( !pnd ){
+ printf( "Unable to open NFC device\n" );
+ nfc_close( pnd );
+ return EXIT_FAILURE;
+ }
+
+ // initialize device as reader
+ if( nfc_initiator_init( pnd ) < 0 ){
+ nfc_perror( pnd, "nfc_initiator_init" );
+ nfc_close( pnd );
+ return EXIT_FAILURE;
+ }
+
+ printf( "Device %s opened: '%s'\n\n", nfc_device_get_name(pnd), nfc_device_get_connstring(pnd) );
+
+ nfc_target nt;
+
+ // connect to a target device
+ if( nfc_connect_target( pnd, &nt ) ){
+ nfc_close( pnd );
+ return EXIT_FAILURE;
+ };
+
+ // send the message to the wallet
+ if( 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 nfc_connect_target( nfc_device *pnd, nfc_target *nt )
+{
+ const nfc_modulation nmMifare[] = { {
+ .nmt = NMT_ISO14443A,
+ .nbr = NBR_106,
+ } };
+
+ printf( "nfc_connect_target: trying to connect to target\n" );
+ int ctr = 2;
+ while( ctr > 0 ){
+ // set uid lenght 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 ) {
+ printf( "nfc_connect_target: failed to connect\n" );
+ } else if( nt->nti.nai.szUidLen > UID_LEN_UPPER || nt->nti.nai.szUidLen < UID_LEN_LOWER ) {
+ printf( "nfc_connect_target: failed to connect\n" );
+ } else {
+ printf( "nfc_connect_target: Target selected!\n" );
+ nfc_display_target_uid( nt );
+ return EXIT_SUCCESS;
+ }
+ sleep(1);
+ ctr--;
+ }
+
+ return EXIT_FAILURE;
+}
+
+void nfc_display_target_uid( nfc_target *nt )
+{
+ printf( "UID: " );
+ for ( unsigned int uidPos = 0; uidPos < nt->nti.nai.szUidLen; uidPos++ ) {
+ printf( "%.2x ", nt->nti.nai.abtUid[uidPos] );
+ }
+ printf("\n\n");
+}
+
diff --git a/src/nfc-wallet/nfc.h b/src/nfc-wallet/nfc.h
new file mode 100644
index 0000000..4416054
--- /dev/null
+++ b/src/nfc-wallet/nfc.h
@@ -0,0 +1,34 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file nfc.h
+* @brief functions used to comunicate over nfc interface
+* @author BOSS Marco
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <nfc/nfc.h>
+
+int nfc_transmit( nfc_context *context, const char *talerPayUrl , size_t urlSize );
+
+int nfc_connect_target( nfc_device *pnd, nfc_target *nt );
+
+void nfc_display_target_uid( nfc_target *nt );
diff --git a/src/nfc-wallet/wallet.c b/src/nfc-wallet/wallet.c
new file mode 100644
index 0000000..4b92f7d
--- /dev/null
+++ b/src/nfc-wallet/wallet.c
@@ -0,0 +1,124 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file wallet.c
+* @brief functions to communicate with taler wallet over nfc
+* @author BOSS Marco
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "wallet.h"
+
+
+int wallet_select_aid( nfc_device *pnd )
+{
+ uint8_t response[] = { 0x00, 0x00 };
+
+ int size = sizeof( select_file ) + sizeof( taler_aid );
+ uint8_t message[size];
+ if( concat_message( select_file, sizeof(select_file), taler_aid, message, size ) )
+ return EXIT_FAILURE;
+
+ printf( "wallet_select_aid: Selecting Taler apk using AID: " );
+ for( unsigned int i = 0; i < sizeof(taler_aid); ++i )
+ printf( "%.2x", taler_aid[i] );
+ printf( "\n" );
+
+ if( nfc_initiator_transceive_bytes( pnd, message, size, response, sizeof(response), TRANSMIT_TIMEOUT ) < 0 ) {
+ printf( "wallet_select_aid: Failed to select apk\n\n" );
+ return EXIT_FAILURE;
+ }
+
+ return check_response( response, sizeof(response) );
+}
+
+int wallet_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( concat_message( put_data, sizeof(put_data), (const uint8_t*)msg, message, size ) )
+ return EXIT_FAILURE;
+
+ printf( "wallet_put_messsage: Sending 'PUT DATA' command to wallet\n" );
+
+ if( nfc_initiator_transceive_bytes( pnd, message, size, response, sizeof(response), TRANSMIT_TIMEOUT ) < 0 ) {
+ printf( "wallet_put_message: Failed to put message\n\n" );
+ return EXIT_FAILURE;
+ }
+
+ return check_response( response, sizeof(response) );
+}
+
+
+int wallet_transmit( nfc_device *pnd, const char *msg, size_t msgLen )
+{
+ if( !msg ) {
+ printf( "wallet_transmit: No message to send\n\n" );
+ return EXIT_FAILURE;
+ }
+
+ if( wallet_select_aid( pnd ) )
+ return EXIT_FAILURE;
+ printf( "wallet_transmit: Taler wallet apk selected\n\n" );
+ if( wallet_put_message( pnd, msg, msgLen ) )
+ return EXIT_FAILURE;
+ printf( "wallet_transmit: Transmitted message to taler wallet\n\n");
+
+ return EXIT_SUCCESS;
+}
+
+int check_response( uint8_t *response, uint8_t responseLen )
+{
+ if( strcmp((char*)response, APDU_SUCCESS ) == 0 ){
+ printf("Transmission success\n");
+ } else {
+ printf("Transmission failure, return code: ");
+ for( uint8_t i = 0; i < responseLen; ++i ){
+ printf( "%.2x ", response[i] );
+ }
+ printf("\n");
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+int concat_message(const uint8_t* command, size_t commandSize, const uint8_t* message, uint8_t *retMsg, size_t returnSize )
+{
+ if( !command || !message ){
+ printf( "concat_message: command and message can't be null" );
+ return EXIT_FAILURE;
+ }
+
+ uint8_t i = 0;
+ for( ; i < commandSize; ++i ){
+ retMsg[i] = command[i];
+ }
+ for( ; i < returnSize; ++i){
+ retMsg[i] = message[i - commandSize];
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/nfc-wallet/wallet.h b/src/nfc-wallet/wallet.h
new file mode 100644
index 0000000..4d51088
--- /dev/null
+++ b/src/nfc-wallet/wallet.h
@@ -0,0 +1,57 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file wallet.h
+* @brief functions to communicate with taler wallet over nfc
+* @author BOSS Marco
+*/
+
+#ifndef WALLET_H
+#define WALLET_H
+
+#include <nfc/nfc.h>
+
+
+// New AID
+// static uint8_t taler_aid[] = { 0xF0, 0x00, 0x54, 0x41, 0x4c, 0x45, 0x52 };
+
+// Demo AID until uptade
+static const uint8_t taler_aid[] = { 0xA0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01 };
+
+#define TRANSMIT_TIMEOUT 500
+
+// 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 };
+
+
+
+int wallet_select_aid( nfc_device *pnd );
+
+int wallet_put_message( nfc_device *pnd, const char *msg, size_t msgSize );
+
+int wallet_transmit( nfc_device* pnd, const char *msg, size_t msgLen );
+
+int concat_message( const uint8_t* command, size_t commandSize, const uint8_t *message, uint8_t *retMsg, size_t returnSize );
+
+int check_response( uint8_t *response, uint8_t responseLen );
+
+#endif // WALLET_H
diff --git a/src/taler-processing/communication.c b/src/taler-processing/communication.c
new file mode 100644
index 0000000..a442a29
--- /dev/null
+++ b/src/taler-processing/communication.c
@@ -0,0 +1,220 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file communication.c
+* @brief functions to communicate with taler backend
+* @author BOSS Marco
+*/
+
+#include <string.h>
+#include <stdbool.h>
+
+#include "communication.h"
+#include "nfc-wallet/wallet.h"
+#include "configuration.h"
+
+int taler_init(CURL **curl)
+{
+ if( *curl != NULL ){
+ printf( "taler_init: curl handle already initialized\n" );
+ return EXIT_FAILURE;
+ }
+
+ // initialize curl
+ CURLcode result = curl_global_init( CURL_GLOBAL_ALL );
+ *curl = curl_easy_init();
+ if( !(*curl) || result != CURLE_OK ){
+ printf( "taler_init: could not inizialize curl handle\n" );
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+void taler_exit( CURL **curl )
+{
+ curl_easy_cleanup(*curl);
+ curl_global_cleanup();
+}
+
+int taler_alloc_string( char **string, size_t size )
+{
+ *string = malloc( size );
+ if( !(*string) ){
+ printf( "taler_alloc: unable to allocate string" );
+ exit( EXIT_FAILURE );
+ }
+ return EXIT_SUCCESS;
+}
+
+static size_t _taler_write_response( void *contents, size_t size, size_t nmemb, void *userp )
+{
+ size_t realSize = size * nmemb;
+ struct TalerResponse *response = (struct TalerResponse *)userp;
+
+ char *tempString = realloc( response->string, response->size + realSize + 1 );
+ if( !tempString ) {
+ printf( "Allocation failure" );
+ return EXIT_FAILURE;
+ }
+
+ response->string = tempString;
+ memcpy(&( response->string[response->size] ), contents, realSize );
+ response->size += realSize;
+ response->string[response->size] = 0;
+
+ return realSize;
+}
+
+int taler_create_order_req( ProductOrder *product )
+{
+ char buffer[256];
+
+ sprintf( buffer, JSON_ORDER, product->product, product->currency, product->amount, product->product );
+
+ char* temp = realloc( product->orderRequest, strlen(buffer) + 1 );
+ if( !temp ){
+ printf( "could not allocate order\n" );
+ return EXIT_FAILURE;
+ }
+
+ product->orderRequest = temp;
+ strcpy( product->orderRequest, buffer );
+ printf( "Created order Request: \n%s\n\n", product->orderRequest );
+
+ return EXIT_SUCCESS;
+}
+
+int taler_create_order( CURL *curl, ProductOrder *product )
+{
+ // reset the response size
+ product->response->size = 0;
+
+ // set the url
+ char url[ strlen(BACKEND_BASE_URL) + strlen( ORDER ) + 1 ];
+ sprintf( url, "%s%s", BACKEND_BASE_URL, ORDER );
+ curl_easy_setopt( curl, CURLOPT_URL, url );
+
+ // set the authentication headers
+ struct curl_slist *list = NULL;
+ list = curl_slist_append( list, AUTH_HEADER );
+ 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, _taler_write_response );
+ curl_easy_setopt( curl, CURLOPT_WRITEDATA, (void *)product->response );
+
+ // perform the call
+ CURLcode result = curl_easy_perform( curl );
+ if( result != CURLE_OK ){
+ printf( "could not communicate with \"%s\"\n", url );
+ return EXIT_FAILURE;
+ }
+
+ // reset the curl options
+ curl_easy_reset( curl );
+
+ // clean up
+ curl_slist_free_all( list );
+
+ return EXIT_SUCCESS;
+}
+
+int taler_check_payment_status( CURL *curl, ProductOrder *product )
+{
+ // reset the response size
+ product->response->size = 0;
+
+ // set the url
+ curl_easy_setopt( curl, CURLOPT_URL, product->checkUrl );
+
+ // set the authentication headers
+ struct curl_slist *list = NULL;
+ list = curl_slist_append( list, AUTH_HEADER );
+ curl_easy_setopt( curl, CURLOPT_HTTPHEADER, list );
+
+ // curl option "get"
+ curl_easy_setopt( curl, CURLOPT_HTTPGET, true );
+
+ // pass the write function and the struct to write to
+ curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, _taler_write_response );
+ curl_easy_setopt( curl, CURLOPT_WRITEDATA, (void *)product->response );
+
+ // perform the call
+ CURLcode result = curl_easy_perform(curl);
+ if( result != CURLE_OK ){
+ printf( "could not communicate with \"%s\"\n", product->checkUrl );
+ return EXIT_FAILURE;
+ }
+
+ // reset the curl options
+ curl_easy_reset( curl );
+
+ // clean up
+ curl_slist_free_all( list );
+
+ return EXIT_SUCCESS;
+}
+
+int taler_parse_json( const TalerResponse *response, const char *memberName, char **returnStr, bool isBoolean )
+{
+ if( !(*returnStr) )
+ taler_alloc_string( returnStr, 1 );
+ char *result = NULL;
+ char *temp = NULL;
+ char mbr[64];
+
+ if( isBoolean ){
+ // If the wanted member is of type boolean
+ sprintf( mbr, "\"%s\": true", memberName );
+ if( (temp = strstr( response->string, mbr)) != NULL )
+ result = "true";
+ else
+ result = "false";
+ }else{
+ // String type members
+ sprintf( mbr, "\"%s\":", memberName );
+ if( (temp = strstr( response->string, mbr )) != NULL ){
+ if( (temp = strstr( response->string, ": ")) != NULL ){
+ result = strtok( temp, "\"");
+ result = strtok( NULL, "\"");
+ }
+ }
+ }
+ if( !result ){
+ printf( "taler_parse_json: no member named \"%s\" found!\n\n", memberName );
+ return EXIT_FAILURE;
+ }
+ temp = realloc( *returnStr, strlen(result) + 1 );
+ if( !temp ){
+ printf( "taler_parse_json: could not allocate memory for member\n" );
+ return EXIT_FAILURE;
+ }
+ *returnStr = temp;
+ strcpy( *returnStr, result );
+
+ return EXIT_SUCCESS;
+}
+
+
diff --git a/src/taler-processing/communication.h b/src/taler-processing/communication.h
new file mode 100644
index 0000000..f65b36d
--- /dev/null
+++ b/src/taler-processing/communication.h
@@ -0,0 +1,51 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file communication.h
+* @brief functions to communicate with taler backend
+* @author BOSS Marco
+*/
+
+
+#ifndef COMM_H
+#define COMM_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <curl/curl.h>
+
+#include "product.h"
+
+int taler_init( CURL **curl );
+
+void taler_exit( CURL **curl );
+
+int taler_alloc_string( char **string, size_t size );
+
+int taler_create_order_req( ProductOrder *product );
+
+int taler_create_order( CURL *curl, ProductOrder *product );
+
+int taler_check_payment_status( CURL *curl, ProductOrder *product );
+
+int taler_parse_json( const TalerResponse *response, const char *memberName, char **returnStr, bool isBoolean );
+
+#endif // COMM_H
diff --git a/src/taler-processing/product.c b/src/taler-processing/product.c
new file mode 100644
index 0000000..5adfc18
--- /dev/null
+++ b/src/taler-processing/product.c
@@ -0,0 +1,126 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file product.c
+* @brief defined a product order with the attributes of the product and
+the links used to communicate with taler. Provides setter methods to set
+the attributes.
+* @author BOSS Marco
+*/
+
+#include <string.h>
+
+#include "product.h"
+#include "configuration.h"
+#include "taler-processing/communication.h"
+
+void product_reset( ProductOrder *product )
+{
+ product->amount = NULL;
+ product->product = NULL;
+ product->paid = false;
+}
+
+int product_init( ProductOrder *product, const char *currency )
+{
+ if( !product ){
+ printf( "product_init: product order struct must be provided\n" );
+ return EXIT_FAILURE;
+ }
+
+ // 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 = malloc( sizeof(TalerResponse) );
+ if( !product->response ){
+ printf( "product_init: unable to allocate memory for response struct\n" );
+ return EXIT_FAILURE;
+ }
+ if( taler_alloc_string( &(product->response->string), 1 ) )
+ return EXIT_FAILURE;
+ if( taler_alloc_string( &(product->orderID), 1 ) )
+ return EXIT_FAILURE;
+ if( taler_alloc_string( &(product->orderRequest), 1 ) )
+ return EXIT_FAILURE;
+ if( taler_alloc_string( &(product->payUrl), 1 ) )
+ return EXIT_FAILURE;
+ if( taler_alloc_string( &(product->checkUrl), 1 ) )
+ return EXIT_FAILURE;
+ if( taler_alloc_string( &(product->currency), strlen(currency) + 1 ) )
+ return EXIT_FAILURE;
+ strcpy( product->currency, currency );
+ product->amount = NULL;
+ product->product = NULL;
+ product->paid = false;
+
+ return EXIT_SUCCESS;
+}
+
+void product_exit( ProductOrder *product )
+{
+ free( product->response->string );
+ free( product->response );
+ free( product->orderID );
+ free( product->orderRequest );
+ free( product->payUrl );
+ free( product->checkUrl );
+ free( product->currency );
+ product->amount = NULL;
+ product->product = NULL;
+ product->paid = false;
+}
+
+int product_set_check_url( ProductOrder *product )
+{
+ size_t len = strlen(BACKEND_BASE_URL) + strlen( CHECK );
+ char *url = realloc( product->checkUrl, len + strlen(ORDER_CHECK) + strlen(product->orderID) + 1 );
+ if( !url ){
+ printf( "could not allocate memory for order url\n" );
+ return EXIT_FAILURE;
+ }
+
+ product->checkUrl = url;
+ sprintf( product->checkUrl, "%s%s%s%s", BACKEND_BASE_URL, CHECK, ORDER_CHECK, product->orderID );
+ printf( "Url to check payment: %s\n\n", product->checkUrl );
+
+ return EXIT_SUCCESS;
+}
+
+int product_set_order_id( ProductOrder *product )
+{
+ return taler_parse_json( product->response, JSON_ORDER_ID, &(product->orderID), false );
+}
+
+int product_set_pay_url( ProductOrder *product )
+{
+ return taler_parse_json( product->response, JSON_PAY_URI, &(product->payUrl), false );
+}
+
+int product_set_paid_status( ProductOrder *product )
+{
+ char *temp = NULL;
+ if( taler_alloc_string( &temp, 1) == EXIT_SUCCESS ){
+ taler_parse_json( product->response, JSON_PAID, &temp, true );
+ if( strcmp( temp, "true" ) == 0 )
+ product->paid = true;
+ free(temp);
+ return EXIT_SUCCESS;
+ }
+
+ return EXIT_FAILURE;
+}
diff --git a/src/taler-processing/product.h b/src/taler-processing/product.h
new file mode 100644
index 0000000..8b8fd61
--- /dev/null
+++ b/src/taler-processing/product.h
@@ -0,0 +1,67 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+* @file product.h
+* @brief defined a product order with the attributes of the product and
+the links used to communicate with taler. Provides setter methods to set
+the attributes.
+* @author BOSS Marco
+*/
+
+#ifndef PRODUCT_H
+#define PRODUCT_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+typedef struct TalerResponse{
+ char *string;
+ size_t size;
+} TalerResponse;
+
+typedef struct ProductOrder{
+ char *product;
+ char *currency;
+ char *amount;
+ char *orderRequest;
+ char *orderID;
+ char *checkUrl;
+ char *payUrl;
+ bool paid;
+ TalerResponse *response;
+} ProductOrder;
+
+
+int product_init( ProductOrder *product, const char* currency );
+
+void product_exit( ProductOrder *product );
+
+void product_reset( ProductOrder *product );
+
+int product_set_check_url( ProductOrder *product );
+
+int product_set_order_id( ProductOrder *product );
+
+int product_set_pay_url( ProductOrder *product );
+
+int product_set_paid_status( ProductOrder *product );
+
+#endif // PRODUCT_H
diff --git a/src/target.mk b/src/target.mk
new file mode 100644
index 0000000..bb77a0f
--- /dev/null
+++ b/src/target.mk
@@ -0,0 +1,6 @@
+TARGET_USER = pi
+TARGET_ADDRESS = 192.168.3.10
+SSH_PORT = 22
+CROSS_TOOLS = $(HOME)/embedded/x-tools
+CROSS = armv8-rpi3-linux-gnueabihf
+TARGET_ARCH = armv8