*/
#include <webrtc.h>
+#include <webrtc_internal.h>
#include <media_format.h>
#include <appcore-efl.h>
#include <Elementary.h>
CURRENT_STATUS_SEND_LOCAL_DESCRIPTION,
CURRENT_STATUS_START_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE,
CURRENT_STATUS_STOP_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE,
+ CURRENT_STATUS_CREATE_PRIVATE_SIGNALING_SERVER,
+ CURRENT_STATUS_CONNECT_TO_PRIVATE_SIGNALING_SERVER,
};
enum {
gint32 local_peer_id;
int server_status;
+ /* for private network */
+ webrtc_signaling_client_h signaling_client;
+ bool is_connected;
+
webrtc_h webrtc;
webrtc_data_channel_h channels[MAX_CHANNEL_LEN];
int channel_index;
static connection_s g_conns[MAX_CONNECTION_LEN];
static int g_conn_index;
+static webrtc_signaling_server_h g_inner_signaling_server;
+
static void win_del(void *data, Evas_Object *obj, void *event)
{
elm_exit();
g_print("webrtc_unset_negotiation_needed_cb() success\n");
}
+static void __signaling_message_cb(webrtc_signaling_message_type_e type, const char *message, void *user_data)
+{
+ connection_s *conn = (connection_s *)user_data;
+
+ g_print("__signaling_message_cb(), type[%d] message[%s] conn[%p]\n", type, message, conn);
+
+ if (type == SIGNALING_MESSAGE_TYPE_CONNECTED) {
+ g_print("\n[from SERVER > CONNECTED %s]\n", message);
+ conn->is_connected = true;
+
+ } else if (type == SIGNALING_MESSAGE_TYPE_DISCONNECTED) {
+ g_print("\n[from SERVER > DISCONNECTED %s]\n", message);
+ conn->is_connected = false;
+
+ } else if (type == SIGNALING_MESSAGE_TYPE_SESSION_ESTABLISHED) {
+ g_print("\n[from SERVER > SESSION_ESTABLISHED with %s]\n", message);
+
+ } else if (type == SIGNALING_MESSAGE_TYPE_SESSION_CLOSED) {
+ g_print("\n[from SERVER > SESSION_CLOSED with %s]\n", message);
+
+ } else if (type == SIGNALING_MESSAGE_TYPE_SDP) {
+ g_print("\n[from SERVER > SDP]\n%s\n", message);
+ if (conn->remote_desc)
+ free(conn->remote_desc);
+ conn->remote_desc = strdup(message);
+
+ } else if (type == SIGNALING_MESSAGE_TYPE_ICE_CANDIDATE) {
+ g_print("\n[from SERVER > ICE]\n%s\n", message);
+ conn->ice_candidates = g_list_append(conn->ice_candidates, strdup(message));
+ }
+}
+
+static void _webrtc_signaling_connect(int index, const char *ip, int port)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ if (strlen(g_signaling_server) > 0) {
+ g_printerr("server[%s] is already set by 'ss'\n", g_signaling_server);
+ return;
+ }
+
+ ret = webrtc_signaling_connect(ip, port, __signaling_message_cb, &g_conns[index], &g_conns[index].signaling_client);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_printerr("failed to webrtc_signaling_connect()\n");
+ else
+ g_print("webrtc_signaling_connect() success\n");
+}
+
+static void _webrtc_signaling_disconnect(int index)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ ret = webrtc_signaling_disconnect(g_conns[index].signaling_client);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_printerr("failed to webrtc_signaling_disconnect()\n");
+ else
+ g_print("webrtc_signaling_disconnect() success\n");
+}
+
+static void _webrtc_signaling_request_session(int index, int peer_id)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ ret = webrtc_signaling_request_session(g_conns[index].signaling_client, peer_id);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_printerr("failed to webrtc_signaling_request_session()\n");
+ else
+ g_print("webrtc_signaling_request_session() success\n");
+}
+
+static void _webrtc_signaling_send_message(int index, const char *message)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ ret = webrtc_signaling_send_message(g_conns[index].signaling_client, message);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_printerr("failed to webrtc_signaling_send_message()\n");
+ else
+ g_print("webrtc_signaling_send_message() success\n");
+}
+
static void __ice_candidate_cb(webrtc_h webrtc, const char *candidate, void *user_data)
{
g_print("__ice_candidate_cb() is invoked\n");
g_print("\n[to SERVER > ICE]\n%s\n", candidate);
- soup_websocket_connection_send_text(g_conns[g_conn_index].ws_conn, candidate);
+ if (g_conns[g_conn_index].ws_conn)
+ soup_websocket_connection_send_text(g_conns[g_conn_index].ws_conn, candidate);
+ else if (g_conns[g_conn_index].is_connected)
+ _webrtc_signaling_send_message(g_conn_index, candidate);
}
static void _webrtc_set_ice_candidate_cb(int index)
if (!uri)
return;
+ if (g_conns[g_conn_index].signaling_client) {
+ g_printerr("already set by 'scc'\n");
+ return;
+ }
+
if (strlen(uri) > strlen("0.0.0.0")) {
ret = __copy_string_arr(dest_arr, uri);
if (ret != 0)
static void _request_session(int index, int remote_peer_id)
{
- gchar *msg;
-
- if (!g_conns[index].ws_conn) {
+ if (!g_conns[index].ws_conn && !g_conns[index].is_connected) {
g_printerr("server[%s] is not connected\n", g_signaling_server);
return;
}
- if (soup_websocket_connection_get_state(g_conns[index].ws_conn) != SOUP_WEBSOCKET_STATE_OPEN) {
- g_printerr("websocket is not opened\n");
- return;
- }
+ if (g_conns[index].ws_conn) {
+ gchar *msg;
+ if (soup_websocket_connection_get_state(g_conns[index].ws_conn) != SOUP_WEBSOCKET_STATE_OPEN) {
+ g_printerr("websocket is not opened\n");
+ return;
+ }
- msg = g_strdup_printf("SESSION %d", remote_peer_id);
+ msg = g_strdup_printf("SESSION %d", remote_peer_id);
- g_print("\n[to SERVER > %s]\n", msg);
- soup_websocket_connection_send_text(g_conns[index].ws_conn, msg);
+ g_print("\n[to SERVER > %s]\n", msg);
+ soup_websocket_connection_send_text(g_conns[index].ws_conn, msg);
+ g_free(msg);
- g_free(msg);
+ } else {
+ _webrtc_signaling_request_session(index, remote_peer_id);
+ }
}
static void _send_local_description(int index, bool is_offer)
{
char *desc;
- if (!g_conns[index].ws_conn) {
+ if (!g_conns[index].ws_conn && !g_conns[index].is_connected) {
g_printerr("server[%s] is not connected\n", g_signaling_server);
return;
}
desc = is_offer ? g_conns[index].offer : g_conns[index].answer;
g_print("\n[to SERVER > local description]\n%s\n", desc);
- soup_websocket_connection_send_text(g_conns[index].ws_conn, desc);
+
+ if (g_conns[index].ws_conn)
+ soup_websocket_connection_send_text(g_conns[index].ws_conn, desc);
+ else
+ _webrtc_signaling_send_message(index, desc);
}
gulong _connect_signal(GObject *obj, const char *signal_name, GCallback callback, gpointer user_data)
SoupURI *proxy_uri;
const char *https_aliases[] = {"wss", NULL};
+ if (g_conns[index].signaling_client) {
+ g_printerr("already set by 'scc'\n");
+ return;
+ }
+
if (strlen(g_proxy) == 0) {
session = soup_session_new_with_options(SOUP_SESSION_SSL_STRICT, TRUE,
SOUP_SESSION_HTTPS_ALIASES, https_aliases, NULL);
(GAsyncReadyCallback) __websocket_connected_cb, &g_conns[index]);
}
+static void _webrtc_signaling_server_create(int port)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ ret = webrtc_signaling_server_create(port, &g_inner_signaling_server);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_printerr("failed to webrtc_signaling_server_create()\n");
+ else
+ g_print("webrtc_signaling_server_create() success, port[%d] g_inner_signaling_server[%p]\n", port, g_inner_signaling_server);
+}
+
+static void _webrtc_signaling_server_destroy(void)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ ret = webrtc_signaling_server_destroy(g_inner_signaling_server);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_printerr("failed to webrtc_signaling_server_destroy()\n");
+ else
+ g_print("webrtc_signaling_server_destroy() success\n");
+}
+
+static void _webrtc_signaling_server_start(void)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ ret = webrtc_signaling_server_start(g_inner_signaling_server);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_printerr("failed to webrtc_signaling_server_start()\n");
+ else
+ g_print("webrtc_signaling_server_start() success\n");
+}
+
+static void _webrtc_signaling_server_stop(void)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ ret = webrtc_signaling_server_stop(g_inner_signaling_server);
+ if (ret != WEBRTC_ERROR_NONE)
+ g_printerr("failed to webrtc_signaling_server_stop()\n");
+ else
+ g_print("webrtc_signaling_server_stop() success\n");
+}
+
void quit_program()
{
int i;
_webrtc_media_packet_source_set_buffer_state_changed_cb(g_conn_index, g_conns[g_conn_index].packet_sources[i].source_id);
}
+ } else if (strncmp(cmd, "ssc", 3) == 0) {
+ g_conns[g_conn_index].menu_state = CURRENT_STATUS_CREATE_PRIVATE_SIGNALING_SERVER;
+
+ } else if (strncmp(cmd, "ssd", 3) == 0) {
+ _webrtc_signaling_server_destroy();
+
+ } else if (strncmp(cmd, "sss", 3) == 0) {
+ _webrtc_signaling_server_start();
+
+ } else if (strncmp(cmd, "sst", 3) == 0) {
+ _webrtc_signaling_server_stop();
+
+ } else if (strncmp(cmd, "scc", 3) == 0) {
+ g_conns[g_conn_index].menu_state = CURRENT_STATUS_CONNECT_TO_PRIVATE_SIGNALING_SERVER;
+
+ } else if (strncmp(cmd, "scd", 3) == 0) {
+ _webrtc_signaling_disconnect(g_conn_index);
+
} else {
g_print("unknown menu \n");
}
g_print("sd. Send local description\n");
g_print("sp. Start pushing packet to media packet source\t");
g_print("tp. Stop pushing packet to media packet source\n");
+ g_print("-------------------------------- Private Signaling Server -------------------------------\n");
+ g_print("ssc. Create signaling server\t");
+ g_print("ssd. Destroy signaling server\n");
+ g_print("sss. Start signaling server\t");
+ g_print("sst. Stop signaling server\n");
+ g_print("scc. Connect to signaling server\t");
+ g_print("scd. Disconnect from signaling server\n");
g_print("-----------------------------------------------------------------------------------------\n");
g_print("=========================================================================================\n");
}
} else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_STOP_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE) {
g_print("*** input media packet source id to stop pushing packet.\n");
+ } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_CREATE_PRIVATE_SIGNALING_SERVER) {
+ g_print("*** input port.\n");
+
+ } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_CONNECT_TO_PRIVATE_SIGNALING_SERVER) {
+ if (g_conns[g_conn_index].cnt == 0)
+ g_print("*** input server ip.\n");
+ else if (g_conns[g_conn_index].cnt == 1)
+ g_print("*** input port.\n");
+
} else {
g_print("*** unknown status.\n");
quit_program();
reset_menu_state();
break;
}
+ case CURRENT_STATUS_CREATE_PRIVATE_SIGNALING_SERVER: {
+ value = atoi(cmd);
+ _webrtc_signaling_server_create(value);
+ reset_menu_state();
+ break;
+ }
+ case CURRENT_STATUS_CONNECT_TO_PRIVATE_SIGNALING_SERVER: {
+ static char *ip = NULL;
+
+ if (strlen(g_signaling_server) > 0) {
+ g_printerr("server[%s] is already set by 'ss'\n", g_signaling_server);
+ reset_menu_state();
+ break;
+ }
+
+ switch (g_conns[g_conn_index].cnt) {
+ case 0:
+ ip = strdup(cmd);
+ g_conns[g_conn_index].cnt++;
+ break;
+ case 1:
+ value = atoi(cmd);
+ _webrtc_signaling_connect(g_conn_index, ip, value);
+ g_conns[g_conn_index].cnt = 0;
+ if (ip) {
+ free(ip);
+ ip = NULL;
+ }
+ reset_menu_state();
+ break;
+ }
+ break;
+ }
}
g_timeout_add(100, timeout_menu_display, 0);