taler-mdb

GNU Taler Extensions and Integrations
Log | Files | Refs | Submodules | README | LICENSE

commit 66cae837bbdfc9fa67f5d2923694c25f976233ad
parent 0c551b634d5b8be9e358ef039cc43aff6045394c
Author: BOSS_Marco <bossm8@students.bfh.ch>
Date:   Fri,  1 Nov 2019 11:02:19 +0100

merged jsonIntegrity

Diffstat:
Msrc/communication.c | 280++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/communication.h | 2+-
Msrc/configuration.h | 38++++++++++++++++++++++++--------------
Msrc/main.c | 43+++++++++++++++++++++++++------------------
Msrc/nfc.c | 22++++++++++++----------
Msrc/product.c | 48++++++++++++++++++++++++++++++++++++------------
Msrc/wallet.c | 2+-
Msrc/wallet.h | 12------------
8 files changed, 256 insertions(+), 191 deletions(-)

diff --git a/src/communication.c b/src/communication.c @@ -25,210 +25,244 @@ along with #include <string.h> #include <stdbool.h> +#include <jansson.h> #include "communication.h" #include "wallet.h" #include "configuration.h" -int taler_init (CURL **curl) +int taler_init(CURL **curl) { - if ( *curl != NULL ) - { - printf ("taler_init: curl handle already initialized\n"); + CURLcode result; + + 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"); + /* initialize curl */ + 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) +void taler_exit( CURL **curl ) { - curl_easy_cleanup (*curl); - curl_global_cleanup (); + curl_easy_cleanup(*curl); + curl_global_cleanup(); } -int taler_alloc_string (char **string, size_t size) +int taler_alloc_string( char **string, size_t size ) { - *string = malloc (size); - if ( ! (*string) ) - { - printf ("taler_alloc: unable to allocate string"); - exit (EXIT_FAILURE); + *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) +static size_t _taler_write_response( void *contents, size_t size, size_t nmemb, + void *userp ) { + char *tempString; size_t realSize = size * nmemb; - struct TalerResponse *response = (struct TalerResponse *) userp; + struct TalerResponse *response = (struct TalerResponse *)userp; - char *tempString = realloc (response->string, response->size + realSize + 1); - if ( ! tempString ) - { - printf ("Allocation failure"); + 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); + memcpy(&( response->string[response->size] ), contents, realSize ); response->size += realSize; response->string[response->size] = 0; return realSize; } -int taler_create_order_req (ProductOrder *product) +int taler_create_order_req( ProductOrder *product ) { - char buffer[256]; - - sprintf (buffer, JSON_ORDER, product->product, product->currency, - product->amount, product->product); + json_t *orderReq; + char* temp; + + /* create the string representing the amount, e.g. "KUDOS:2.5" ( +2 because of ':' and '\0' ) */ + char amountStr[ strlen(product->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(FULLFILLMENT_URL) + strlen(FULLFILLMENT_MSG) + + strlen(product->product) + 2 ]; + + /* create the strings declared earlier */ + sprintf( amountStr, "%s:%s", product->currency, product->amount ); + sprintf( fulfillmentUrl, "%s%s%s!", FULLFILLMENT_URL, FULLFILLMENT_MSG, + product->product ); + + /* create the json object for the order request */ + orderReq = json_pack( "{ s: { s:s, s:s, s:s }}", JSON_REQ_ORDER, + JSON_REQ_SUMMARY, product->product, JSON_REQ_AMOUNT, + amountStr, JSON_REQ_FULFILLMENT, fulfillmentUrl ); + if( !orderReq ){ + printf( "taler_create_order_req: error creating json object\n" ); + return EXIT_FAILURE; + } - char*temp = realloc (product->orderRequest, strlen (buffer) + 1); - if ( ! temp ) - { - printf ("could not allocate order\n"); + /* create the string to send to taler in compact format */ + char *buffer = json_dumps( orderReq, JSON_COMPACT ); + if( !buffer ){ + printf("taler_create_order_req: error converting json to string\n"); return EXIT_FAILURE; } + /* allocate memory for the string and copy it into the product */ + 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); + 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 taler_create_order (CURL *curl, ProductOrder *product) +int taler_create_order( CURL *curl, ProductOrder *product ) { - // reset the response size + char url[ strlen(BACKEND_BASE_URL) + strlen( ORDER ) + 1 ]; + struct curl_slist *list = NULL; + CURLcode result; + + /* 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 url */ + 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); + /* set the authentication headers */ + 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 */ + 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); + /* reset the curl options */ + curl_easy_reset( curl ); + + /* clean up */ + curl_slist_free_all( list ); - // clean up - curl_slist_free_all (list); + + printf("%s\n", product->response->string ); return EXIT_SUCCESS; } -int taler_check_payment_status (CURL *curl, ProductOrder *product) +int taler_check_payment_status( CURL *curl, ProductOrder *product ) { - // reset the response size + struct curl_slist *list = NULL; + CURLcode result; + + /* reset the response size */ product->response->size = 0; - // set the url - curl_easy_setopt (curl, CURLOPT_URL, product->checkUrl); + /* 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); + /* set the authentication headers */ + list = curl_slist_append( list, AUTH_HEADER ); + curl_easy_setopt( curl, CURLOPT_HTTPHEADER, list ); - // curl option "get" - curl_easy_setopt (curl, CURLOPT_HTTPGET, true); + /* 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); + /* 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); + /* perform the call */ + 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); + /* reset the curl options */ + curl_easy_reset( curl ); - // clean up - curl_slist_free_all (list); + /* clean up */ + curl_slist_free_all( list ); return EXIT_SUCCESS; } -int taler_parse_json (const TalerResponse *response, const char *memberName, - char **returnStr, bool isBoolean) +int taler_parse_json( const TalerResponse *response, const char *memberName, + char **returnStr ) { - if ( ! (*returnStr) ) - taler_alloc_string (returnStr, 1); - char *result = NULL; + /* json variables */ + json_error_t error; + json_t *root = 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"; + + /* if the provided string was not allocated before allocate initial size 1 to + * realloc later */ + if( !(*returnStr) ) + taler_alloc_string( returnStr, 1 ); + + /* load the json with th string provided from taler in the response struct */ + root = json_loads( response->string, JSON_DISABLE_EOF_CHECK, &error ); + if( !root ){ + printf("taler_parse_json: %s\n", error.text ); + return EXIT_FAILURE; } - 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, "\""); - } - } + char *result = NULL; + if( json_unpack( root, "{s:s}", memberName, &result ) < 0 ){ + printf( "taler_parse_json: no member named \"%s\" found!\n", memberName ); + json_decref( root ); + return EXIT_FAILURE; } - if ( ! result ) - { - printf ("taler_parse_json: no member named \"%s\" found!\n\n", memberName); + if( !result ){ + printf( "taler_parse_json: no member named \"%s\" found!\n", memberName ); + json_decref( root ); return EXIT_FAILURE; } - temp = realloc (*returnStr, strlen (result) + 1); - if ( ! temp ) - { - printf ("taler_parse_json: could not allocate memory for member\n"); + + temp = realloc( *returnStr, strlen(result) + 1 ); + if( !temp ){ + printf( "taler_parse_json: could not allocate memory for member\n" ); + json_decref( root ); return EXIT_FAILURE; } *returnStr = temp; - strcpy (*returnStr, result); + strcpy( *returnStr, result ); + json_decref( root ); return EXIT_SUCCESS; } diff --git a/src/communication.h b/src/communication.h @@ -47,6 +47,6 @@ 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); + char **returnStr); #endif // COMM_H diff --git a/src/configuration.h b/src/configuration.h @@ -26,11 +26,17 @@ along with #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="; +#include <stdio.h> +#include <inttypes.h> -static const char*const BACKEND_BASE_URL = "https://backend.demo.taler.net"; +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 FULLFILLMENT_URL = "taler://fulfillment-success"; +static const char* const FULLFILLMENT_MSG = "/Enjoy+your+"; static const char*const AUTH_HEADER = "Authorization: ApiKey sandbox"; @@ -38,17 +44,21 @@ 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"; +/* json order request keys */ +static const char*const JSON_REQ_ORDER = "order"; +static const char*const JSON_REQ_SUMMARY = "summary"; +static const char*const JSON_REQ_AMOUNT = "amount"; +static const char*const JSON_REQ_FULFILLMENT = "fulfillment_url"; + +/* 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 }; -//// 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" - "}"; +/* 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 }; #endif // URL_H diff --git a/src/main.c b/src/main.c @@ -45,14 +45,15 @@ nfc_context *context = NULL; void *start_nfc_transmission (void *ignored) { - // supress warning about unused variable + /* 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) + + /* start endless transmission loop (until threads gets cancelled) */ while ( 1 ) { if ( pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL) != 0 ) @@ -72,7 +73,7 @@ void *start_nfc_transmission (void *ignored) int main ( ) { - // initialize nfc + /* initialize nfc */ nfc_init (&context); if ( ! context ) { @@ -80,7 +81,7 @@ int main ( ) return EXIT_FAILURE; } - // inizialize taler + /* inizialize taler */ CURL *curl = NULL; if ( taler_init (&curl) ) { @@ -88,7 +89,7 @@ int main ( ) return EXIT_FAILURE; } - // inizialize product + /* inizialize product */ if ( product_init (&product, CURRENCY) ) { printf ("Unable to init product\n"); @@ -103,32 +104,32 @@ int main ( ) if ( getchar () == 'x' ) break; - // DEMO snickers + /* DEMO snickers */ product.amount = "0.1"; product.product = "Snickers"; - // create the order request + /* create the order request */ taler_create_order_req (&product); - // create the order + /* create the order */ while ( taler_create_order (curl, &product) ) ; - // store the order id into the struct + /* store the order id into the struct */ product_set_order_id (&product); - // store the url to check wheter the payment happened or not + /* store the url to check wheter the payment happened or not */ product_set_check_url (&product); - // check the payment status for the first time + /* 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 + /* 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 + /* start a thread to send payment request to taler wallet */ pthread_t nfcThread; if ( pthread_create (&nfcThread, NULL, start_nfc_transmission, NULL) ) { @@ -136,7 +137,7 @@ int main ( ) return EXIT_FAILURE; } - // check the payment status, if paid exit while loop and end thread transmitting nfc messages + /* check the payment status, if paid exit while loop and end thread transmitting nfc messages */ while ( ! product.paid ) { printf ("Order payment processing\n"); @@ -144,18 +145,24 @@ int main ( ) sleep (5); while ( taler_check_payment_status (curl, &product) ) ; - // set the boolean paid member of ProductOrder struct + /* 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 + /* ----------------- + Here comes the code for releasing the product + ----------------- */ + + + /* 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 ) { @@ -168,12 +175,12 @@ int main ( ) fflush (stdout); } - // reset the product + /* reset the product */ product_reset (&product); } - // clear all initialized data + /* clear all initialized data */ nfc_exit (context); product_exit (&product); taler_exit (&curl); diff --git a/src/nfc.c b/src/nfc.c @@ -30,7 +30,7 @@ along with #include "wallet.h" -// upper and lower bounds for mifare targets uid length +/* upper and lower bounds for mifare targets uid length */ #define UID_LEN_UPPER 7 #define UID_LEN_LOWER 4 @@ -38,6 +38,7 @@ along with int nfc_transmit (nfc_context *context, const char *talerPayUrl, size_t urlSize) { nfc_device *pnd = NULL; + nfc_target nt; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MEMORY LEAK? NFC OPEN? @@ -49,7 +50,7 @@ int nfc_transmit (nfc_context *context, const char *talerPayUrl, size_t urlSize) return EXIT_FAILURE; } - // initialize device as reader + /* initialize device as reader */ if ( nfc_initiator_init (pnd) < 0 ) { nfc_perror (pnd, "nfc_initiator_init"); @@ -60,9 +61,7 @@ int nfc_transmit (nfc_context *context, const char *talerPayUrl, size_t urlSize) 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 + /* connect to a target device */ if ( nfc_connect_target (pnd, &nt) ) { nfc_close (pnd); @@ -70,15 +69,15 @@ int nfc_transmit (nfc_context *context, const char *talerPayUrl, size_t urlSize) } ; - // send the message to the wallet + /* 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 + /* 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 + /* clean up */ nfc_initiator_deselect_target (pnd); nfc_close (pnd); @@ -87,16 +86,19 @@ int nfc_transmit (nfc_context *context, const char *talerPayUrl, size_t urlSize) int 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, } }; 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 ) + /* 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 ) diff --git a/src/product.c b/src/product.c @@ -26,6 +26,7 @@ the attributes. */ #include <string.h> +#include <jansson.h> #include "product.h" #include "configuration.h" @@ -46,7 +47,8 @@ int product_init (ProductOrder *product, const char *currency) 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 + /* 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 ) { @@ -109,26 +111,48 @@ int product_set_check_url (ProductOrder *product) int product_set_order_id (ProductOrder *product) { return taler_parse_json (product->response, JSON_ORDER_ID, - &(product->orderID), false); + &(product->orderID)); } int product_set_pay_url (ProductOrder *product) { - return taler_parse_json (product->response, JSON_PAY_URI, &(product->payUrl), - false); + return taler_parse_json (product->response, JSON_PAY_URI, &(product->payUrl)); } int product_set_paid_status (ProductOrder *product) { - char *temp = NULL; - if ( taler_alloc_string (&temp, 1) == EXIT_SUCCESS ) + json_error_t error; + json_t *root = NULL; + + /* variable to extract the boolean value out of json object */ + int b = -1; + + root = json_loads( product->response->string, JSON_DISABLE_EOF_CHECK, &error); + if( !root ) + { + printf("taler_parse_json: %s\n", error.text ); + return EXIT_FAILURE; + } + + /* extract the boolean value of paid out of the json object */ + if ( json_unpack( root, "{s:b}", JSON_PAID, &b ) < 0 ) + { + printf("taler_parse_json: no value \"%s\" found!\n", JSON_PAID ); + json_decref( root ); + return EXIT_FAILURE; + } + + json_decref(root); + + /* set the paid status to true or false */ + if( b == true || b == false ) { - taler_parse_json (product->response, JSON_PAID, &temp, true); - if ( strcmp (temp, "true") == 0 ) - product->paid = true; - free (temp); - return EXIT_SUCCESS; + product->paid = b; + }else + { + printf( "product_set_paid_status: json parsing failed\n" ); + return EXIT_FAILURE; } - return EXIT_FAILURE; + return EXIT_SUCCESS; } diff --git a/src/wallet.c b/src/wallet.c @@ -28,7 +28,7 @@ along with #include <string.h> #include "wallet.h" - +#include "configuration.h" int wallet_select_aid (nfc_device *pnd) { diff --git a/src/wallet.h b/src/wallet.h @@ -29,20 +29,8 @@ along with #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);