diff options
Diffstat (limited to 'src/anastasis/anastasis-gtk_action.c')
-rw-r--r-- | src/anastasis/anastasis-gtk_action.c | 120 |
1 files changed, 116 insertions, 4 deletions
diff --git a/src/anastasis/anastasis-gtk_action.c b/src/anastasis/anastasis-gtk_action.c index 6d2bdb9..984fef5 100644 --- a/src/anastasis/anastasis-gtk_action.c +++ b/src/anastasis/anastasis-gtk_action.c @@ -37,6 +37,17 @@ /** + * After how long does our long-poller time out? + */ +#define LP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) + +/** + * Next time we schedule the #long_task. + */ +static struct GNUNET_TIME_Absolute long_next; + + +/** * Are we currently processing an action? */ bool AG_in_action; @@ -2197,7 +2208,92 @@ action_secret_selecting (void) /** - * FIXME. + * Function called with the results of #ANASTASIS_redux_action on "poll". + * + * @param cls closure, NULL + * @param error_code Error code + * @param response new state as result or config information of a provider + */ +static void +long_action_cb (void *cls, + enum TALER_ErrorCode error_code, + json_t *response); + + +/** + * Schedules the 'poll' action. + * + * @param cls NULL + */ +static void +long_task (void *cls) +{ + json_t *tspec; + + (void) cls; + AG_long_task = NULL; + if (GNUNET_TIME_absolute_is_future (long_next)) + { + AG_long_task = GNUNET_SCHEDULER_add_at (long_next, + &long_task, + NULL); + return; + } + long_next = GNUNET_TIME_relative_to_absolute (LP_TIMEOUT); + tspec = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_time_rel ("timeout", + LP_TIMEOUT)); + AG_long_action + = ANASTASIS_redux_action (AG_redux_state, + "poll", + tspec, + &long_action_cb, + NULL); + json_decref (tspec); +} + + +/** + * Function called with the results of #ANASTASIS_redux_action on "poll". + * + * @param cls closure, NULL + * @param error_code Error code + * @param response new state as result or config information of a provider + */ +static void +long_action_cb (void *cls, + enum TALER_ErrorCode error_code, + json_t *response) +{ + AG_long_action = NULL; + switch (error_code) + { + case TALER_EC_NONE: + /* continued below */ + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "'poll' action failed: %s\n", + TALER_ErrorCode_get_hint (error_code)); + /* simply try again */ + AG_long_task = GNUNET_SCHEDULER_add_now (&long_task, + NULL); + return; + } + if (NULL != AG_ra) + { + GNUNET_break (0); + ANASTASIS_redux_action_cancel (AG_ra); + } + AG_action_cb (NULL, + TALER_EC_NONE, + response); +} + + +/** + * The user must select the next challenge to solve + * during the recovery process. */ static void action_challenge_selecting (void) @@ -2225,6 +2321,7 @@ action_challenge_selecting (void) const char *type; const char *uuid; struct TALER_Amount cost; + bool async = false; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("instructions", &instructions), @@ -2234,6 +2331,9 @@ action_challenge_selecting (void) &provider), GNUNET_JSON_spec_string ("uuid", &uuid), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_bool ("async", + &async)), GNUNET_JSON_spec_end () }; @@ -2266,7 +2366,14 @@ action_challenge_selecting (void) uuid, NULL)) continue; - + if (async && + (NULL == AG_long_task) ) + { + long_next = GNUNET_TIME_UNIT_ZERO_ABS; + AG_long_task + = GNUNET_SCHEDULER_add_now (&long_task, + NULL); + } gtk_list_store_insert_with_values ( ls, NULL, @@ -2436,6 +2543,10 @@ action_challenge_selecting (void) } +/** + * An Anastasis provider requires payment for a challenge. + * Give opportunity to the user to pay. + */ static void action_challenge_paying (void) { @@ -3015,7 +3126,8 @@ action_challenge_solving (void) /** - * FIXME. + * The recovery process was finished. Show the recovered secret to the + * user. */ static void action_recovery_finished (void) @@ -3187,11 +3299,11 @@ AG_action_cb (void *cls, GNUNET_break (0); return; } - } else { json_decref (AG_redux_state); + AG_stop_long_action (); AG_redux_state = json_incref (response); } if ( (TALER_EC_ANASTASIS_TRUTH_UNKNOWN == error_code) || |