commit 2b5d168b9589b1ee38405d72dee52866217bd685
parent ff9d1def4acae789683f3a86abc1f4c3ef87bce1
Author: Tellenbach Reto <tellr1@bfh.ch>
Date: Sat, 30 May 2026 11:31:18 +0200
[new] thinker_TalerAPI: make request and handle shutdown
Diffstat:
10 files changed, 665 insertions(+), 145 deletions(-)
diff --git a/thinker/taler_api/CMakeLists.txt b/thinker/taler_api/CMakeLists.txt
@@ -1,6 +1,6 @@
# Project Config
cmake_minimum_required(VERSION 3.13)
-project(taler-api LANGUAGES C )
+project(taler-digitizer LANGUAGES C )
# Langage requirements
set(CMAKE_C_STANDARD 17)
diff --git a/thinker/taler_api/CMakePresets.json b/thinker/taler_api/CMakePresets.json
@@ -7,7 +7,7 @@
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
- "CMAKE_C_FLAGS": "-Wall -Wextra"
+ "CMAKE_C_FLAGS": "-Wall -Wextra -g"
}
}
]
diff --git a/thinker/taler_api/src/CMakeLists.txt b/thinker/taler_api/src/CMakeLists.txt
@@ -1,16 +1,12 @@
-# Add files
-add_executable(taler-api taler-digitizer.c)
-#add_library(digitizer_utils os_installation.c)
+# Add files and libs
+add_executable(taler-digitizer taler-digitizer.c)
-# libs
-find_package(CURL REQUIRED)
find_package(PkgConfig REQUIRED)
-pkg_check_modules(GNUNET REQUIRED gnunetutil)
-# Manage libs
-target_link_libraries(taler-api
- PRIVATE CURL::libcurl gnunetutil
-)
-#include <gnunet/gnunet_util_lib.h>
-#include "taler_digitizer_util.h"
-\ No newline at end of file
+add_subdirectory(lib)
+
+# Manage libs
+target_link_libraries(taler-digitizer
+ PRIVATE bank
+)
+\ No newline at end of file
diff --git a/thinker/taler_api/src/lib/CMakeLists.txt b/thinker/taler_api/src/lib/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Add files
+add_library(bank bank_api_get_config.c bank_api_curl_defaults.c)
+
+find_package(CURL REQUIRED)
+pkg_check_modules(GNUNET REQUIRED gnunetutil)
+
+target_link_libraries(bank
+ PUBLIC CURL::libcurl gnunetutil talerutil
+ PRIVATE talercurl talerjson gnunetutil gnunetcurl gnunetjson jansson
+)
+\ No newline at end of file
diff --git a/thinker/taler_api/src/lib/bank_api_curl_defaults.c b/thinker/taler_api/src/lib/bank_api_curl_defaults.c
@@ -0,0 +1,54 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2018, 2021 Taler Systems SA
+
+ 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 lib/bank_api_curl_defaults.c
+ * @brief curl easy handle defaults
+ * @author Florian Dold
+ */
+#include "taler/taler_curl_lib.h"
+#include "bank_api_curl_defaults.h"
+
+
+CURL *
+TALER_BANK_curl_easy_get_ (const char *url)
+{
+ CURL *eh;
+
+ eh = curl_easy_init ();
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_URL,
+ url));
+ TALER_curl_set_secure_redirect_policy (eh,
+ url);
+ /* Enable compression (using whatever curl likes), see
+ https://curl.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html */
+ GNUNET_break (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_ACCEPT_ENCODING,
+ ""));
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_TCP_FASTOPEN,
+ 1L));
+ return eh;
+}
diff --git a/thinker/taler_api/src/lib/bank_api_curl_defaults.h b/thinker/taler_api/src/lib/bank_api_curl_defaults.h
@@ -0,0 +1,40 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2018 Taler Systems SA
+
+ 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 lib/bank_api_curl_defaults.h
+ * @brief curl easy handle defaults
+ * @author Florian Dold
+ */
+
+#ifndef _TALER_CURL_DEFAULTS_H
+#define _TALER_CURL_DEFAULTS_H
+
+
+#include <gnunet/gnunet_curl_lib.h>
+
+
+/**
+ * Get a curl handle with the right defaults
+ * for the interaction with the lib.
+ *
+ * @param url URL to query
+ */
+CURL *
+TALER_BANK_curl_easy_get_ (const char *url);
+
+#endif /* _TALER_CURL_DEFAULTS_H */
diff --git a/thinker/taler_api/src/lib/bank_api_get_config.c b/thinker/taler_api/src/lib/bank_api_get_config.c
@@ -0,0 +1,138 @@
+#include "bank_api_get_config.h"
+#include "bank_api_curl_defaults.h"
+
+/**
+ * Which revision of the Taler core-bank protocol is implemented
+ * by this library? Used to determine compatibility.
+ */
+#define TALER_PROTOCOL_CURRENT 12
+
+/**
+ * How many revisions back are we compatible to?
+ */
+#define TALER_PROTOCOL_AGE 0
+
+
+/**
+ * Handle for the get config request.
+ */
+struct TALER_BANK_GetConfigHandle
+{
+ /**
+ * The context of this handle
+ */
+ struct GNUNET_CURL_Context *ctx;
+
+ /**
+ * Function to call with the auditor's certification data,
+ * NULL if this has already been done.
+ */
+ TALER_BANK_ConfigCallback config_cb;
+
+ /**
+ * Closure to pass to
+ */
+ void *config_cb_cls;
+
+ /**
+ * Data for the request to get the /config of a bank,
+ * NULL once we are past stage #MHS_INIT.
+ */
+ struct GNUNET_CURL_Job *job;
+
+ /**
+ * The whole request line
+ */
+ char *job_url;
+};
+
+/**
+ * Callback used when http reply arived to a /config request.
+ *
+ * @param cls the `struct TALER_BANK_GetConfigHandle`
+ * @param response_code HTTP response code or 0 on error
+ * @param gresp_obj parsed JSON result, NULL on error, must be a `const json_t *`
+ */
+static void
+response_cb(void *cls,
+ long response_code,
+ const void *response)
+{
+ struct TALER_BANK_GetConfigHandle *bank = cls;
+ const json_t *resp_obj = response;
+
+ struct TALER_BANK_ConfigResponse vr = {
+ .hr.response = resp_obj,
+ .hr.http_status = (unsigned int)response_code
+ };
+
+ bank->job = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received config from URL `%s' with status %ld.\n",
+ bank->job_url,
+ response_code);
+
+ bank->config_cb (bank->config_cb_cls, &vr);
+ TALER_BANK_get_config_cancel(bank);
+}
+
+
+struct TALER_BANK_GetConfigHandle *
+TALER_BANK_get_config ( struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ TALER_BANK_ConfigCallback config_cb,
+ void *config_cb_cls)
+{
+ struct TALER_BANK_GetConfigHandle *bank;
+ CURL *eh;
+
+ bank = GNUNET_new(struct TALER_BANK_GetConfigHandle);
+ bank->config_cb = config_cb;
+ bank->config_cb_cls = config_cb_cls;
+ bank->ctx = ctx;
+ bank->job_url = TALER_url_join(url,"config",NULL);
+ if(NULL == bank->job_url)
+ {
+ GNUNET_break(0);
+ GNUNET_free(bank);
+ return NULL;
+ }
+
+ GNUNET_log( GNUNET_ERROR_TYPE_INFO,
+ "Requesting bank config with URL `%s'.\n",
+ bank->job_url);
+ eh = TALER_BANK_curl_easy_get_(bank->job_url);
+ if(NULL == eh)
+ {
+ GNUNET_break(0);
+ TALER_BANK_get_config_cancel(bank);
+ return NULL;
+ }
+ bank->job = GNUNET_CURL_job_add(bank->ctx,
+ eh,
+ &response_cb,
+ bank);
+ if(NULL == bank->job)
+ {
+ GNUNET_break(0);
+ TALER_BANK_get_config_cancel(bank);
+ return NULL;
+ }
+
+ return bank;
+}
+
+
+
+void
+TALER_BANK_get_config_cancel ( struct TALER_BANK_GetConfigHandle *bank)
+{
+ if(NULL != bank->job)
+ {
+ GNUNET_CURL_job_cancel(bank->job);
+ bank->job = NULL;
+ }
+ GNUNET_free(bank->job_url);
+ GNUNET_free(bank);
+}
+
diff --git a/thinker/taler_api/src/lib/bank_api_get_config.h b/thinker/taler_api/src/lib/bank_api_get_config.h
@@ -0,0 +1,176 @@
+#ifndef BANK_API_GET_CONFIG_H
+#define BANK_API_GET_CONFIG_H
+
+#include "../taler/taler_digitizer_service.h"
+
+
+/**
+ * @brief Information we get from the bank about itself. and is needed for the digitizer
+ */
+struct TALER_BANK_ConfigInformation
+{
+ /**
+ * Name of api
+ */
+ const char *api_name;
+
+ /**
+ * Supported Taler protocol version by the bank.
+ * String in the format current:revision:age using the
+ * semantics of GNU libtool. See
+ * https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+ */
+ const char *version;
+
+ /**
+ * Bank display name to be used in user interfaces.
+ * For consistency use "Taler Bank" if missing.
+ */
+ const char *bank_name;
+
+ /**
+ * Advertised base URL to use when you sharing an URL with another program.
+ */
+ const char *base_url;
+
+ /** If 'true' the server provides local currency conversion support
+ * If 'false' some parts of the API are not supported and return 501
+ */
+ const bool allow_conversion;
+
+ /** If 'true' anyone can register
+ * If 'false' only admin can
+ */
+ const bool allow_registrations;
+
+ /**
+ * If 'true' account can delete themselves
+ * If 'false' only admin can delete accounts
+ */
+ const bool allow_deletions;
+
+ /**
+ * If 'true' anyone can edit their name
+ * If 'false' only admin can
+ */
+ const bool allow_edit_name;
+
+ /**
+ * If 'true' anyone can edit their cashout account
+ * If 'false' only admin can
+ */
+ const bool allow_edit_cashout_payto_uri;
+
+ /**
+ * Default debt limit for newly created accounts
+ */
+ const struct TALER_AmountNBO default_debit_threshold;
+
+
+ /**
+ * Currency used by this bank.
+ */
+ const char *currency;
+
+ /**
+ * How the bank SPA should render this currency.
+ */
+ const struct TALER_CurrencySpecification currency_specification;
+
+ /**
+ * Stand in string for the TAN channel. Not used in the callbacks
+ * when used needs to be addapted
+ * TAN channels supported by the server
+ */
+ const char *supported_tan_channels;
+
+ /**
+ * Wire transfer type supported by the bank.
+ * Defaults to 'iban' is missing
+ */
+ const char *wire_type;
+
+ /**
+ * Wire transfer execution fees. Only applies to bank transactions and withdrawals.
+ */
+ const struct TALER_AmountNBO wire_transfer_fees;
+
+ /**
+ * Minimum wire transfer amount allowed. Only applies to bank transactions and withdrawals.
+ */
+ const struct TALER_AmountNBO min_wire_transfer_amount;
+
+
+ /**
+ * Maximum wire transfer amount allowed. Only applies to bank transactions and withdrawals.
+ */
+ const struct TALER_AmountNBO max_wire_transfer_amount;
+};
+
+/**
+ * Response details for a config request
+ */
+struct TALER_BANK_ConfigResponse
+{
+
+ /**
+ * HTTP response
+ */
+ struct TALER_BANK_HttpResponse hr;
+
+ /**
+ * Details returned depending on the @e http_status.
+ */
+ union
+ {
+
+ /**
+ * Details if status was request was succesfull
+ */
+ struct
+ {
+
+ struct TALER_BANK_ConfigInformation configi;
+
+ } ok;
+
+ } details;
+
+};
+
+
+/**
+ * Function called with information about the bank.
+ *
+ * @param cls closure
+ * @param vr response data
+ */
+typedef void
+(*TALER_BANK_ConfigCallback) (
+ void *cls,
+ const struct TALER_BANK_ConfigResponse *vr);
+
+
+/**
+ * Handle for the get config request.
+ */
+struct TALER_BANK_GetConfigHandle;
+
+
+/**
+ * Obtain config inforamtion about the connected Bank
+ */
+struct TALER_BANK_GetConfigHandle *
+TALER_BANK_get_config ( struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ TALER_BANK_ConfigCallback config_cb,
+ void *config_cb_cls);
+
+/**
+ * Cancel config request. Handles the GNUNet canelation.
+ */
+void
+TALER_BANK_get_config_cancel ( struct TALER_BANK_GetConfigHandle *bank);
+
+
+#endif //BANK_API_GET_CONFIG_H
+\ No newline at end of file
diff --git a/thinker/taler_api/src/taler-digitizer.c b/thinker/taler_api/src/taler-digitizer.c
@@ -1,5 +1,6 @@
#include <gnunet/gnunet_util_lib.h>
#include "taler_digitizer_util.h"
+#include "lib/bank_api_get_config.h"
/**
@@ -18,44 +19,105 @@ static int global_ret;
*/
static int enable_diagnostics;
+/**
+ * Taler Backend url read from configuration file
+ */
+static char *cfg_backend_base_url;
+/**
+ * Currency read from configuration file
+ */
+static char *cfg_currency;
-struct TALER_DIGITIZER_Config
-{
+/**
+ * Minimum balance read from configuration file
+ */
+static unsigned long long cfg_backend_min_balance;
+
+/**
+ * Per-person withdrawal limit read from configuration file
+ */
+static unsigned long long cfg_person_withdrawllimit;
- /**
- * Taler Backend url read from configuration file
- */
- char *backend_base_url;
-
- /**
- * Taler Backend url read from configuration file
- */
- char *currency;
-
- /**
- * Taler Backend url read from configuration file
- */
- unsigned long long backend_min_balance;
-
- /**
- * Taler Backend url read from configuration file
- */
- unsigned long long person_withdrawllimit;
-
- /**
- * Taler Backend url read from configuration file
- */
- struct GNUNET_TIME_Relative person_withdrawl_period;
-
- /**
- * Taler Backend url read from configuration file
- */
- enum GNUNET_GenericReturnValue kyc_functionality;
-
+/**
+ * Per-person withdrawal period read from configuration file
+ */
+static struct GNUNET_TIME_Relative cfg_person_withdrawl_period;
+
+/**
+ * KYC functionality flag read from configuration file
+ */
+static enum GNUNET_GenericReturnValue cfg_kyc_functionality;
+
+/**
+ * Handle to the context for interacting with the bank.
+ */
+static struct GNUNET_CURL_Context *curl_ctx;
+
+/**
+ * Scheduler context for running the @e ctx.
+ */
+static struct GNUNET_CURL_RescheduleContext *reschedule_ctx;
+
+/**
+ * Handle for get_config request
+ */
+static struct TALER_BANK_GetConfigHandle *get_config_handle;
+
+/**
+ * All the variables needed in run() that must be cleaned in shutdown
+ */
+struct TALER_DIGITIZER_State
+{
+ struct GNUNET_CURL_Context *curl_ctx;
+ struct GNUNET_CURL_RescheduleContext *reschedule_ctx;
+ struct TALER_BANK_GetConfigHandle *get_config_handle;
};
+static void
+after_get_config (void *cls,
+ const struct TALER_BANK_ConfigResponse *vr)
+{
+ (void) cls;
+ (void) vr;
+
+ get_config_handle = NULL;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Config Callback\n");
+ GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * @brief Cleanup when no task is scheduled anymore
+ *
+ * @param cls closure
+ */
+static void
+shutdown_task (void *cls)
+{
+ (void)cls;
+
+ if (NULL != get_config_handle)
+ {
+ TALER_BANK_get_config_cancel (get_config_handle);
+ get_config_handle = NULL;
+ }
+ if (NULL != reschedule_ctx)
+ {
+ GNUNET_CURL_gnunet_rc_destroy (reschedule_ctx);
+ reschedule_ctx = NULL;
+ }
+ if (NULL != curl_ctx)
+ {
+ GNUNET_CURL_fini (curl_ctx);
+ curl_ctx = NULL;
+ }
+}
+
+
/**
* @brief Start the application
*
@@ -74,31 +136,26 @@ run (void *cls,
(void) args;
(void) cfgfile;
- printf("Parse Config\n");
-
- struct TALER_DIGITIZER_Config digitizer_config;
-
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Parse Configuration\n");
- //if(enable_diagnostics)GNUNET_CONFIGURATION_enable_diagnostics (cfg);
-
- /* parse the devices, if no config entry is found, a standard is used */
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string(cfg,
- "taler-digitizer",
- "BACKEND_BASE_URL",
- &(digitizer_config.backend_base_url)))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "taler-digitizer",
- "BACKEND_BASE_URL");
- global_ret = EXIT_FAILURE;
- return;
- }
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ "taler-digitizer",
+ "BACKEND_BASE_URL",
+ &cfg_backend_base_url))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "taler-digitizer",
+ "BACKEND_BASE_URL");
+ global_ret = EXIT_FAILURE;
+ return;
+ }
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"taler-digitizer",
"CURRENCY",
- &(digitizer_config.currency)))
+ &cfg_currency))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler-digitizer",
@@ -110,8 +167,8 @@ run (void *cls,
GNUNET_CONFIGURATION_get_value_number (cfg,
"taler-digitizer",
"BANK_MIN_BALANCE",
- &(digitizer_config.backend_min_balance)))
- {
+ &cfg_backend_min_balance))
+ {
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler-digitizer",
"BANK_MIN_BALANCE");
@@ -122,22 +179,21 @@ run (void *cls,
GNUNET_CONFIGURATION_get_value_number (cfg,
"taler-digitizer",
"PERSON_WITHDRAWLLIMIT",
- &(digitizer_config.person_withdrawllimit)))
- {
+ &cfg_person_withdrawllimit))
+ {
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler-digitizer",
"PERSON_WITHDRAWLLIMIT");
global_ret = EXIT_FAILURE;
return;
}
-
+
unsigned long long person_withdrawl_period_number;
- unsigned long long *pwpn = &person_withdrawl_period_number;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (cfg,
"taler-digitizer",
"PERSON_WITHDRAL_PERIOD",
- pwpn))
+ &person_withdrawl_period_number))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler-digitizer",
@@ -145,18 +201,14 @@ run (void *cls,
global_ret = EXIT_FAILURE;
return;
}
- else
- {
- digitizer_config.person_withdrawl_period = GNUNET_TIME_relative_multiply(
- DIGITIZER_PERSON_WITHDRAWL_PERIOD_TIME_UNIT,
- person_withdrawl_period_number);
- }
-
-
- digitizer_config.kyc_functionality = GNUNET_CONFIGURATION_get_value_yesno (cfg,
- "taler-digitizer",
- "KYC_FUNCTIONALITY");
- if(GNUNET_SYSERR == digitizer_config.kyc_functionality)
+ cfg_person_withdrawl_period = GNUNET_TIME_relative_multiply (
+ DIGITIZER_PERSON_WITHDRAWL_PERIOD_TIME_UNIT,
+ person_withdrawl_period_number);
+
+ cfg_kyc_functionality = GNUNET_CONFIGURATION_get_value_yesno (cfg,
+ "taler-digitizer",
+ "KYC_FUNCTIONALITY");
+ if (GNUNET_SYSERR == cfg_kyc_functionality)
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler-digitizer",
@@ -164,15 +216,30 @@ run (void *cls,
global_ret = EXIT_FAILURE;
return;
}
-
- printf("Config URl: %s \n", digitizer_config.backend_base_url);
-}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Config URL: %s\n",
+ cfg_backend_base_url);
+
+ curl_ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
+ &reschedule_ctx);
+ reschedule_ctx = GNUNET_CURL_gnunet_rc_create (curl_ctx);
+ GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+ NULL);
+
+ get_config_handle = TALER_BANK_get_config (curl_ctx,
+ cfg_backend_base_url,
+ &after_get_config,
+ NULL);
+ return;
+}
-int main(int argc, char*const*argv)
-{
+int
+main (int argc,
+ char *const *argv)
+{
int ret;
struct GNUNET_GETOPT_CommandLineOption options[] = {
@@ -187,7 +254,8 @@ int main(int argc, char*const*argv)
argc,
argv,
"taler-digitizer",
- "This is an application for the Cash Digitizer. It accepts cash and transfers it to the Taler Wallet.\n",
+ "This is an application for the Cash Digitizer."
+ " It accepts cash and transfers it to the Taler Wallet.\n",
options,
&run,
NULL);
@@ -197,56 +265,4 @@ int main(int argc, char*const*argv)
if (GNUNET_OK != ret)
return 1;
return global_ret;
-}
-
-
-// void *TALER_DIGITIZER_CheckExchangeConfigCompadibility(void *DigitizerConfig, const struct TALER_EXCHANGE_GetConfigResponse result)
-// {
-
-// }
-
-
-// /*** Init Curl ***/
-// CURL *curl;
-// enum DIGITIZER_ErrorCode ret = 0;
-
-// struct TALER_EXCHANGE_GetConfigResponse *exchange_config;
-
-
-
-
-// if(curl_global_init(CURL_GLOBAL_ALL)!= CURLE_OK)
-// {
-// TALER_LOG_ERROR("curl_global_init() failed at %s:%d\n", __FILE__, __LINE__);
-// return DIGITIZER_EC_GENERIC;
-// }
-
-
-// curl = curl_easy_init();
-// if(NULL == curl)
-// {
-// TALER_LOG_ERROR("curl_easy_init() failed at %s:%d\n", __FILE__, __LINE__);
-// ret = DIGITIZER_EC_GENERIC;
-// }
-// else
-// {
-
-// curl_easy_cleanup(curl);
-// }
-
-// /*
-// // GET /cocnfig
-// if(curl_easy_setopt(curl, CURLOPT_URL, TALER_EXCHANGE_URL) != CURLE_OK)
-// {
-// TALER_LOG_ERROR("curl_easy_setopt() failed at %s:%d\n", __FILE__, __LINE__);
-// ret = DIGITIZER_EC_GENERIC;
-// }
-// else if(curl_easy_perform(curl) != CURLE_OK)
-// {
-// TALER_LOG_ERROR("curl_easy_perform() failed at %s:%d\n", __FILE__, __LINE__);
-// ret = DIGITIZER_EC_GENERIC;
-// }
-// */
-
-// return ret;
-
-\ No newline at end of file
+}
+\ No newline at end of file
diff --git a/thinker/taler_api/src/taler/taler_digitizer_service.h b/thinker/taler_api/src/taler/taler_digitizer_service.h
@@ -0,0 +1,87 @@
+#ifndef _TALER_DIGITIZER_SERVICE_H
+#define _TALER_DIGITIZER_SERVICE_H
+
+
+#include <taler/taler_bank_service.h>
+#include <taler/taler_util.h>
+#include "../lib/bank_api_get_config.h"
+
+/**
+ * How compatible are the protocol version of the bank and this
+ * client? The bits (1,2,4) can be used to test if the auditor's
+ * version is incompatible, older or newer respectively.
+ */
+enum TALER_BANK_VersionCompatibility
+{
+
+ /**
+ * The bank runs exactly the same protocol version.
+ */
+ TALER_BANK_VC_MATCH = 0,
+
+ /**
+ * The bank is too old or too new to be compatible with this
+ * implementation (bit)
+ */
+ TALER_BANK_VC_INCOMPATIBLE = 1,
+
+ /**
+ * The bank is older than this implementation (bit)
+ */
+ TALER_BANK_VC_OLDER = 2,
+
+ /**
+ * The bank is too old to be compatible with
+ * this implementation.
+ */
+ TALER_BANK_VC_INCOMPATIBLE_OUTDATED
+ = TALER_BANK_VC_INCOMPATIBLE
+ | TALER_BANK_VC_OLDER,
+
+ /**
+ * The bank is more recent than this implementation (bit).
+ */
+ TALER_BANK_VC_NEWER = 4,
+
+ /**
+ * The bank is too recent for this implementation.
+ */
+ TALER_BANK_VC_INCOMPATIBLE_NEWER
+ = TALER_BANK_VC_INCOMPATIBLE
+ | TALER_BANK_VC_NEWER,
+
+ /**
+ * We could not even parse the version data.
+ */
+ TALER_BANK_VC_PROTOCOL_ERROR = 8
+
+};
+
+
+/**
+ * General information about the HTTP response we obtained
+ * from the bank for a request.
+ */
+struct TALER_BANK_HttpResponse
+{
+
+ /**
+ * Full response, NULL if body was not in JSON format.
+ */
+ const json_t *response;
+
+
+ /**
+ * HTTP status code for the response.
+ */
+ unsigned int http_status;
+
+ /**
+ * Taler error code, #TALER_EC_NONE on success.
+ */
+ enum TALER_ErrorCode ec;
+
+};
+
+
+#endif
+\ No newline at end of file