gnunet-svn
[Top][All Lists]
Advanced

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

[taler-taler-mdb] 01/01: initial commit


From: gnunet
Subject: [taler-taler-mdb] 01/01: initial commit
Date: Wed, 30 Oct 2019 15:39:12 +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 895f886cbe84c1b3cf1aa7583f30913e9ee052c4
Author: BOSS_Marco <address@hidden>
AuthorDate: Wed Oct 30 15:35:06 2019 +0100

    initial commit
---
 .gitignore                           |  12 ++
 README                               |  31 +++++
 doc/.gitkeep                         |   0
 src/configuration.h                  |  54 +++++++++
 src/main.c                           | 166 ++++++++++++++++++++++++++
 src/makefile                         |  78 +++++++++++++
 src/mdb/.gitkeep                     |   0
 src/nfc-wallet/nfc.c                 | 118 +++++++++++++++++++
 src/nfc-wallet/nfc.h                 |  34 ++++++
 src/nfc-wallet/wallet.c              | 124 ++++++++++++++++++++
 src/nfc-wallet/wallet.h              |  57 +++++++++
 src/taler-processing/communication.c | 220 +++++++++++++++++++++++++++++++++++
 src/taler-processing/communication.h |  51 ++++++++
 src/taler-processing/product.c       | 126 ++++++++++++++++++++
 src/taler-processing/product.h       |  67 +++++++++++
 src/target.mk                        |   6 +
 16 files changed, 1144 insertions(+)

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
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
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

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



reply via email to

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