#ifndef NO_SERVER
#include "juice/juice.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
static void sleep(unsigned int secs) { Sleep(secs * 1000); }
#else
#include <unistd.h>
#endif
#define BUFFER_SIZE 4096
#define TURN_USERNAME "server_test"
#define TURN_PASSWORD "79874638521694"
static juice_server_t *server;
static juice_agent_t *agent1;
static juice_agent_t *agent2;
static bool srflx_success = false;
static bool relay_success = false;
static bool success = false;
static void on_state_changed1(juice_agent_t *agent, juice_state_t state, void *user_ptr);
static void on_state_changed2(juice_agent_t *agent, juice_state_t state, void *user_ptr);
static void on_candidate1(juice_agent_t *agent, const char *sdp, void *user_ptr);
static void on_candidate2(juice_agent_t *agent, const char *sdp, void *user_ptr);
static void on_gathering_done1(juice_agent_t *agent, void *user_ptr);
static void on_gathering_done2(juice_agent_t *agent, void *user_ptr);
static void on_recv1(juice_agent_t *agent, const char *data, size_t size, void *user_ptr);
static void on_recv2(juice_agent_t *agent, const char *data, size_t size, void *user_ptr);
int test_server() {
juice_set_log_level(JUICE_LOG_LEVEL_DEBUG);
juice_server_credentials_t credentials[1];
memset(&credentials, 0, sizeof(credentials));
credentials[0].username = TURN_USERNAME;
credentials[0].password = TURN_PASSWORD;
juice_server_config_t server_config;
memset(&server_config, 0, sizeof(server_config));
server_config.port = 3478;
server_config.credentials = credentials;
server_config.credentials_count = 1;
server_config.max_allocations = 100;
server_config.realm = "Juice test server";
server = juice_server_create(&server_config);
if(juice_server_get_port(server) != 3478) {
printf("juice_server_get_port failed\n");
juice_server_destroy(server);
return -1;
}
juice_config_t config1;
memset(&config1, 0, sizeof(config1));
config1.stun_server_host = "localhost";
config1.stun_server_port = 3478;
juice_turn_server_t turn_server;
memset(&turn_server, 0, sizeof(turn_server));
turn_server.host = "localhost";
turn_server.port = 3478;
turn_server.username = TURN_USERNAME;
turn_server.password = TURN_PASSWORD;
config1.turn_servers = &turn_server;
config1.turn_servers_count = 1;
config1.cb_state_changed = on_state_changed1;
config1.cb_candidate = on_candidate1;
config1.cb_gathering_done = on_gathering_done1;
config1.cb_recv = on_recv1;
config1.user_ptr = NULL;
agent1 = juice_create(&config1);
juice_config_t config2;
memset(&config2, 0, sizeof(config2));
config2.stun_server_host = "localhost";
config2.stun_server_port = 3478;
config2.turn_servers = &turn_server;
config2.turn_servers_count = 1;
config2.cb_state_changed = on_state_changed2;
config2.cb_candidate = on_candidate2;
config2.cb_gathering_done = on_gathering_done2;
config2.cb_recv = on_recv2;
config2.user_ptr = NULL;
agent2 = juice_create(&config2);
char sdp1[JUICE_MAX_SDP_STRING_LEN];
juice_get_local_description(agent1, sdp1, JUICE_MAX_SDP_STRING_LEN);
printf("Local description 1:\n%s\n", sdp1);
juice_set_remote_description(agent2, sdp1);
char sdp2[JUICE_MAX_SDP_STRING_LEN];
juice_get_local_description(agent2, sdp2, JUICE_MAX_SDP_STRING_LEN);
printf("Local description 2:\n%s\n", sdp2);
juice_set_remote_description(agent1, sdp2);
juice_gather_candidates(agent1);
sleep(2);
juice_gather_candidates(agent2);
sleep(2);
juice_destroy(agent1);
juice_destroy(agent2);
juice_server_destroy(server);
sleep(2);
if (srflx_success && relay_success && success) {
printf("Success\n");
return 0;
} else {
printf("Failure\n");
return -1;
}
}
static void on_state_changed1(juice_agent_t *agent, juice_state_t state, void *user_ptr) {
printf("State 1: %s\n", juice_state_to_string(state));
if (state == JUICE_STATE_CONNECTED) {
const char *message = "Hello from 1";
juice_send(agent, message, strlen(message));
}
}
static void on_state_changed2(juice_agent_t *agent, juice_state_t state, void *user_ptr) {
printf("State 2: %s\n", juice_state_to_string(state));
if (state == JUICE_STATE_CONNECTED) {
const char *message = "Hello from 2";
juice_send(agent, message, strlen(message));
}
}
static void on_candidate1(juice_agent_t *agent, const char *sdp, void *user_ptr) {
printf("Candidate 1: %s\n", sdp);
if (strstr(sdp, " typ srflx raddr 0.0.0.0 rport 0"))
srflx_success = true;
if (strstr(sdp, " typ relay raddr 0.0.0.0 rport 0"))
relay_success = true;
if (!strstr(sdp, "relay"))
return;
juice_add_remote_candidate(agent2, sdp);
}
static void on_candidate2(juice_agent_t *agent, const char *sdp, void *user_ptr) {
printf("Candidate 2: %s\n", sdp);
if (strstr(sdp, " typ srflx raddr 0.0.0.0 rport 0"))
srflx_success = true;
if (strstr(sdp, " typ relay raddr 0.0.0.0 rport 0"))
relay_success = true;
if (!strstr(sdp, "relay"))
return;
juice_add_remote_candidate(agent1, sdp);
}
static void on_gathering_done1(juice_agent_t *agent, void *user_ptr) {
printf("Gathering done 1\n");
juice_set_remote_gathering_done(agent2); }
static void on_gathering_done2(juice_agent_t *agent, void *user_ptr) {
printf("Gathering done 2\n");
juice_set_remote_gathering_done(agent1); }
static void on_recv1(juice_agent_t *agent, const char *data, size_t size, void *user_ptr) {
char buffer[BUFFER_SIZE];
if (size > BUFFER_SIZE - 1)
size = BUFFER_SIZE - 1;
memcpy(buffer, data, size);
buffer[size] = '\0';
printf("Received 1: %s\n", buffer);
success = true;
}
static void on_recv2(juice_agent_t *agent, const char *data, size_t size, void *user_ptr) {
char buffer[BUFFER_SIZE];
if (size > BUFFER_SIZE - 1)
size = BUFFER_SIZE - 1;
memcpy(buffer, data, size);
buffer[size] = '\0';
printf("Received 2: %s\n", buffer);
success = true;
}
#endif