/**
 * We've paired up a client session with an incoming CADET request.
 * Initiate set intersection work.
 *
 * @param s client session to start intersection for
 */
static void
start_intersection (struct BobServiceSession *s)
{
  struct GNUNET_HashCode set_sid;

  GNUNET_CRYPTO_hash (&s->session_id,
                      sizeof (struct GNUNET_HashCode),
                      &set_sid);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Got session with key %s and %u elements, starting intersection.\n",
              GNUNET_h2s (&s->session_id),
              (unsigned int) s->total);

  s->intersection_op
    = GNUNET_SET_prepare (&s->cadet->peer,
                          &set_sid,
                          NULL,
                          GNUNET_SET_RESULT_REMOVED,
                          &cb_intersection_element_removed,
                          s);
  if (GNUNET_OK !=
      GNUNET_SET_commit (s->intersection_op,
                         s->intersection_set))
  {
    GNUNET_break (0);
    s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE;
    prepare_client_end_notification (s);
    return;
  }
  GNUNET_SET_destroy (s->intersection_set);
  s->intersection_set = NULL;
}
static void
listen_cb (void *cls,
           const struct GNUNET_PeerIdentity *other_peer,
           const struct GNUNET_MessageHeader *context_msg,
           struct GNUNET_SET_Request *request)
{
  struct GNUNET_SET_OperationHandle *oh;

  GNUNET_assert (NULL != context_msg);
  GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_TEST);
  GNUNET_SET_listen_cancel (listen_handle);
  oh = GNUNET_SET_accept (request,
                          GNUNET_SET_RESULT_FULL,
                          &result_cb_set2, NULL);
  GNUNET_SET_commit (oh, set2);
}
/**
 * Start the set operation.
 *
 * @param cls closure, unused
 */
static void
start (void *cls)
{
  struct GNUNET_MessageHeader context_msg;

  context_msg.size = htons (sizeof context_msg);
  context_msg.type = htons (GNUNET_MESSAGE_TYPE_DUMMY);

  listen_handle = GNUNET_SET_listen (config,
                                     GNUNET_SET_OPERATION_UNION,
                                     &app_id,
                                     &listen_cb, NULL);
  oh1 = GNUNET_SET_prepare (&local_id,
                            &app_id,
                            &context_msg,
                            GNUNET_SET_RESULT_SYMMETRIC,
                            &result_cb_set1, NULL);
  GNUNET_SET_commit (oh1, set1);
}
static void
listen_cb (void *cls,
           const struct GNUNET_PeerIdentity *other_peer,
           const struct GNUNET_MessageHeader *context_msg,
           struct GNUNET_SET_Request *request)
{
  GNUNET_assert (NULL != context_msg);
  GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "listen cb called\n");
  GNUNET_SET_listen_cancel (listen_handle);
  listen_handle = NULL;
  oh2 = GNUNET_SET_accept (request,
                           GNUNET_SET_RESULT_SYMMETRIC,
                           &result_cb_set2,
                           NULL);
  GNUNET_SET_commit (oh2,
                     set2);
}
/**
 * Start the set operation.
 *
 * @param cls closure, unused
 */
static void
start (void *cls)
{
  struct GNUNET_SET_OperationHandle *oh;
  struct GNUNET_MessageHeader context_msg;

  context_msg.size = htons (sizeof context_msg);
  context_msg.type = htons (GNUNET_MESSAGE_TYPE_TEST);
  listen_handle = GNUNET_SET_listen (config,
                                     GNUNET_SET_OPERATION_INTERSECTION,
                                     &app_id,
                                     &listen_cb, NULL);
  oh = GNUNET_SET_prepare (&local_id,
                           &app_id,
                           &context_msg,
                           GNUNET_SET_RESULT_FULL,
                           &result_cb_set1, NULL);
  GNUNET_SET_commit (oh, set1);
}