static void
address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
                    struct Session *session,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
                    const struct GNUNET_ATS_Information *atsi,
                    uint32_t ats_count)
{
  static int stage = 0;
  if (0 == stage)
  {
    if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
    {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with correct address `%s'\n",
                    GNUNET_i2s (&address->peer));
        ret = 0;
    }
    else
    {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with invalid address `%s'\n",
                    GNUNET_i2s (&address->peer));
        ret = 1;
    }

    if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 0: Callback with incorrect ats info \n");
      ret = 1;
    }
    stage ++;
    GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
    GNUNET_SCHEDULER_add_now (&end, NULL);
  }
}
static void
address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
                    struct Session *session,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
                    const struct GNUNET_ATS_Information *ats,
                    uint32_t ats_count)
{
  static int suggest_p0 = GNUNET_NO;
  static int suggest_p1 = GNUNET_NO;
  static int running = GNUNET_NO;

  if (0 == memcmp (&address->peer, &p[0].id,
                   sizeof (struct GNUNET_PeerIdentity)))
  {
    suggest_p0 = GNUNET_YES;;

    if (s_ha[0] != NULL)
      GNUNET_free (s_ha[0]);
    s_ha[0] = GNUNET_HELLO_address_copy (address);

    GNUNET_ATS_suggest_address_cancel (atsh, &p[0].id);
  }
  if (0 == memcmp (&address->peer, &p[1].id,
                   sizeof (struct GNUNET_PeerIdentity)))
  {
    suggest_p1 = GNUNET_YES;

    if (s_ha[1] != NULL)
      GNUNET_free (s_ha[1]);
    s_ha[1] = GNUNET_HELLO_address_copy (address);

    GNUNET_ATS_suggest_address_cancel (atsh, &p[1].id);
  }


  if ((GNUNET_NO == running) && (GNUNET_YES == suggest_p0) && (GNUNET_YES == suggest_p1))
  {
      running = GNUNET_YES;
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have address suggestion for both peers\n");
      GNUNET_SCHEDULER_add_now (&test_performance_api, NULL);
  }

}
static void
address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
                    struct Session *session,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
                    const struct GNUNET_ATS_Information *atsi,
                    uint32_t ats_count)
{
  static int stage = 0;
  if (0 == stage)
  {
    GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
    if (GNUNET_OK == compare_addresses(address, session, &test_hello_address, test_session))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback for correct address `%s'\n",
                  GNUNET_i2s (&address->peer));
      ret = 0;
    }
    else
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 0: Callback with incorrect address `%s'\n",
                    GNUNET_i2s (&address->peer));
      ret = 1;
      GNUNET_SCHEDULER_add_now (&end, NULL);
      return;
    }

    if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 0: Callback with incorrect ats info \n");
      ret = 1;
      GNUNET_SCHEDULER_add_now (&end, NULL);
      return;
    }

    /* Update address */
    /* Prepare ATS Information */
    test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
    test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
    test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
    test_ats_info[1].value = htonl(3);
    test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
    test_ats_info[1].value = htonl(30);
    test_ats_count = 2;

    GNUNET_ATS_address_update (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);

    /* Request address */
    GNUNET_ATS_suggest_address (sched_ats, &p.id);
    stage ++;
  }
  else if (1 == stage)
  {
      GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
      if (GNUNET_OK == compare_addresses(address, session, &test_hello_address, test_session))
      {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 1: Callback with correct address `%s'\n",
                    GNUNET_i2s (&address->peer));
        ret = 0;
      }
      else
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 1: Callback with incorrect address `%s'\n",
                    GNUNET_i2s (&address->peer));
        ret = 1;
      }

      if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 1: Callback with incorrect ats info \n");
        ret = 1;
        GNUNET_SCHEDULER_add_now (&end, NULL);
        return;
      }

      GNUNET_SCHEDULER_add_now (&end, NULL);
  }
}
static void
address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
                    struct Session *session,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
                    const struct GNUNET_ATS_Information *atsi,
                    uint32_t ats_count)
{
  static int stage = 0;
  unsigned int bw_in = ntohl(bandwidth_in.value__);
  unsigned int bw_out = ntohl(bandwidth_out.value__);
  if (0 == stage)
  {
    if (GNUNET_OK == compare_addresses (address, session, &test_hello_address[0], test_session[0]))
    {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n",
                    stage,
                    GNUNET_i2s (&address->peer));
        ret = 0;
    }
    else
    {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n",
            stage,
                    GNUNET_i2s (&address->peer));
        ret = 1;
    }

    if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n",
          stage);
      ret = 1;
    }

    if (bw_in > wan_quota_in)
    {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN inbound quota %u bigger than allowed quota %llu \n",
            bw_in, wan_quota_in);
        ret = 1;
    }
    else
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN inbound quota %u, allowed quota %llu \n",
          bw_in, wan_quota_in);

    if (bw_out > wan_quota_out)
    {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN outbound quota %u bigger than allowed quota %llu \n",
            bw_out, wan_quota_out);
        ret = 1;
    }
    else
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN outbound quota %u, allowed quota %llu \n",
          bw_out, wan_quota_out);

    if (1 == ret)
    {
      GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
      GNUNET_SCHEDULER_add_now (&end, NULL);
      return;
    }

    stage ++;

    GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
    GNUNET_ATS_suggest_address (sched_ats, &p[1].id);
    return;
  }
  if (1 == stage)
  {
    if (GNUNET_OK == compare_addresses (address, session, &test_hello_address[1], test_session[1]))
    {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n",
                    stage,
                    GNUNET_i2s (&address->peer));
        ret = 0;
    }
    else
    {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n",
                    stage,
                    GNUNET_i2s (&address->peer));
        ret = 1;
    }

    if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n",
          stage);
      ret = 1;
    }

    if (bw_in > wan_quota_in)
    {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN inbound quota %u bigger than allowed quota %llu \n",
            bw_in, wan_quota_in);
        ret = 1;
    }
    else
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN inbound quota %u, allowed quota %llu \n",
          bw_in, wan_quota_in);

    if (bw_out > wan_quota_out)
    {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN outbound quota %u bigger than allowed quota %llu \n",
            bw_out, wan_quota_out);
        ret = 1;
    }
    else
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN outbound quota %u, allowed quota %llu \n",
          bw_out, wan_quota_out);

    if (1 == ret)
    {
      GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
      GNUNET_SCHEDULER_add_now (&end, NULL);
      return;
    }

    stage ++;
    GNUNET_ATS_suggest_address_cancel (sched_ats, &p[1].id);
    GNUNET_SCHEDULER_add_now (&end, NULL);

    return;
  }
}