/**
 * Adapter function called to destroy a connection to
 * a service.
 *
 * @param cls closure
 * @param op_result service handle returned from the connect adapter
 */
static void
session_disconnect_adapter (void *cls, void *op_result)
{
  struct GNUNET_SECRETSHARING_Session **sp = cls;
  if (NULL != *sp)
  {
    GNUNET_SECRETSHARING_session_destroy (*sp);
    *sp = NULL;
  }
}
/**
 * Adapter function called to destroy a connection to
 * a service.
 *
 * @param cls closure
 * @param op_result service handle returned from the connect adapter
 */
static void
session_disconnect_adapter (void *cls, void *op_result)
{
  struct GNUNET_SECRETSHARING_Session **sp = cls;
  unsigned int n = (sp - session_handles);

  GNUNET_assert (*sp == session_handles[n]);

  if (NULL != *sp)
  {
    GNUNET_SECRETSHARING_session_destroy (*sp);
    *sp = NULL;
  }

  GNUNET_assert (NULL != connect_ops[n]);
  connect_ops[n] = NULL;

  if (GNUNET_YES == in_shutdown)
    return;

  // all peers received their secret
  if (num_generated == num_peers)
  {
    int i;

    // only do decryption if requested by the user
    if (GNUNET_NO == decrypt)
    {
      GNUNET_SCHEDULER_shutdown ();
      return;
    }

    decrypt_start = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay);
    decrypt_deadline = GNUNET_TIME_absolute_add (decrypt_start, timeout);

    // compute g^42 as the plaintext which we will decrypt and then
    // cooperatively decrypt
    GNUNET_SECRETSHARING_plaintext_generate_i (&reference_plaintext, 42);
    GNUNET_SECRETSHARING_encrypt (&common_pubkey, &reference_plaintext, &ciphertext);

    for (i = 0; i < num_peers; i++)
      connect_ops[i] =
          GNUNET_TESTBED_service_connect (NULL, peers[i], "secretsharing", &decrypt_connect_complete, NULL,
                                          &decrypt_connect_adapter, &decrypt_disconnect_adapter, &decrypt_handles[i]);
  }
}