CURRENT_STATUS_SETTING_PROXY,
CURRENT_STATUS_CHANGE_CONNECTION,
CURRENT_STATUS_REQUEST_SESSION,
+ CURRENT_STATUS_REQUEST_JOIN_ROOM,
CURRENT_STATUS_SEND_LOCAL_DESCRIPTION,
CURRENT_STATUS_START_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE,
CURRENT_STATUS_STOP_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE,
SERVER_STATUS_DISCONNECTED,
SERVER_STATUS_CONNECTED,
SERVER_STATUS_SESSION_ESTABLISHED,
+ SERVER_STATUS_ROOM_ESTABLISHED,
SERVER_STATUS_ERROR_FOUND
};
"DISCONNECTED",
"CONNECTED",
"SESSION_ESTABLISHED",
+ "ROOM_ESTABLISHED",
"ERROR_FOUND",
};
typedef struct _connection_s {
SoupWebsocketConnection *ws_conn;
gint32 local_peer_id;
+ int remote_peer_id;
int server_status;
+ bool is_for_room;
+ bool is_offer;
+ int room_source_type;
+
/* for private network */
webrtc_signaling_client_h signaling_client;
bool is_connected;
{
Evas_Object *eo = NULL;
- g_print("[%s][%d] name=%s\n", __func__, __LINE__, name);
+ if (!w || !h) {
+ g_printerr("w[%p] or h[%p] is NULL\n", w, h);
+ return NULL;
+ }
eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
if (eo) {
elm_win_borderless_set(eo, EINA_TRUE);
evas_object_smart_callback_add(eo, "delete,request", win_del, NULL);
elm_win_screen_size_get(eo, NULL, NULL, w, h);
- g_print("window size: %d x %d\n", *w, *h);
+ g_print("eo[%p], window size: %d x %d\n", eo, *w, *h);
evas_object_resize(eo, *w, *h);
elm_win_autodel_set(eo, EINA_TRUE);
elm_win_alpha_set(eo, EINA_TRUE);
}
+
return eo;
}
evas = evas_object_evas_get(eo_parent);
eo = evas_object_image_add(evas);
- g_print("eo [%p]\n", eo);
+ g_print("eo[%p]\n", eo);
return eo;
}
for (i = 0; i < MAX_CONNECTION_LEN + 1; i++) {
eo = (i == 0) ? &g_eo_mine : &g_conns[i - 1].render.eo;
*eo = create_image_object(ad->win);
+ if (!*eo) {
+ g_print("failed to create evas image object\n");
+ continue;
+ }
evas_object_image_size_set(*eo, ad->win_width / 2, ad->win_height / 2);
evas_object_image_fill_set(*eo, 0, 0, ad->win_width / 2, ad->win_height / 2);
evas_object_resize(*eo, ad->win_width / 2, ad->win_height / 2);
return 0;
}
-static void _webrtc_add_media_source(int index, int value)
+static void _webrtc_add_media_source(int index, int value, unsigned int *source_id)
{
int ret = WEBRTC_ERROR_NONE;
- unsigned int source_id = 0;
+ unsigned int _source_id = 0;
int i;
if (value - 1 <= WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET) {
i = _get_empty_packet_sources_index(index);
RET_IF(i == -1, "media packet source can be added up to %d", MAX_MEDIA_PACKET_SOURCE_LEN);
}
- ret = webrtc_add_media_source(g_conns[index].webrtc, type, &source_id);
+ ret = webrtc_add_media_source(g_conns[index].webrtc, type, &_source_id);
RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
if (type == WEBRTC_MEDIA_SOURCE_TYPE_MIC) {
g_printerr("failed to __get_sound_stream_info()\n");
} else {
- ret = webrtc_mic_source_set_sound_stream_info(g_conns[index].webrtc, source_id, g_conns[index].source.stream_info);
+ ret = webrtc_mic_source_set_sound_stream_info(g_conns[index].webrtc, _source_id, g_conns[index].source.stream_info);
if (ret != WEBRTC_ERROR_NONE)
g_printerr("failed to webrtc_mic_source_set_sound_stream_info(), ret[0x%x]\n", ret);
}
return;
}
if (type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET) {
- g_conns[index].packet_sources[i].source_id = source_id;
+ g_conns[index].packet_sources[i].source_id = _source_id;
g_mutex_init(&g_conns[index].packet_sources[i].mutex);
g_cond_init(&g_conns[index].packet_sources[i].cond);
}
switch (type) {
case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_AUDIO:
case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_VIDEO:
- ret = webrtc_add_media_source_internal(g_conns[index].webrtc, type, &source_id);
+ ret = webrtc_add_media_source_internal(g_conns[index].webrtc, type, &_source_id);
RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
break;
default:
}
}
- g_print("_webrtc_add_media_source() success, source_id[%u]\n", source_id);
+ g_print("_webrtc_add_media_source() success, source_id[%u]\n", _source_id);
+ if (source_id)
+ *source_id = _source_id;
}
static void _webrtc_remove_media_source(int index, unsigned int source_id)
g_print("webrtc_media_source_get_video_resolution() success, source_id[%u], [%dx%d]\n", source_id, width, height);
}
-#define VIDEO_WIDTH 352
-#define VIDEO_HEIGHT 288
+#define VIDEO_WIDTH 320
+#define VIDEO_HEIGHT 240
#define VIDEO_FRAME_RATE 30
#define AUDIO_CHANNEL 1
#define AUDIO_SAMPLERATE 8000
g_print("webrtc_media_source_get_mute() success, source_id[%d], mute_status[%d]\n", source_id, mute_status);
}
+static void _webrtc_create_offer(connection_s *conn)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ RET_IF(!conn, "conn is NULL");
+
+ if (conn->offer) {
+ free(conn->offer);
+ conn->offer = NULL;
+ }
+
+ ret = webrtc_create_offer(conn->webrtc, NULL, &conn->offer);
+ RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+ g_print("webrtc_create_offer() success\noffer:\n%s\n", conn->offer);
+}
+
+static void _webrtc_create_answer(connection_s *conn)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ RET_IF(!conn, "conn is NULL");
+
+ if (conn->answer) {
+ free(conn->answer);
+ conn->answer = NULL;
+ }
+
+ ret = webrtc_create_answer(conn->webrtc, NULL, &conn->answer);
+ RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+ g_print("webrtc_create_answer() success\nanswer:\n%s\n", conn->answer);
+}
+
+static void _webrtc_set_local_description(connection_s *conn, bool is_offer)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ RET_IF(!conn, "conn is NULL");
+
+ ret = webrtc_set_local_description(conn->webrtc, is_offer ? conn->offer : conn->answer);
+ RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+ g_print("webrtc_set_local_description() success\n");
+}
+
+static void _webrtc_set_remote_description(connection_s *conn)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ RET_IF(!conn, "conn is NULL");
+
+ ret = webrtc_set_remote_description(conn->webrtc, conn->remote_desc);
+ RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+ g_print("webrtc_set_remote_description() success\n");
+}
+
+static void __foreach_ice_candidate(gpointer data, gpointer user_data)
+{
+ int ret = WEBRTC_ERROR_NONE;
+
+ ret = webrtc_add_ice_candidate(g_conns[g_conn_index].webrtc, (const char *)data);
+ RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+ g_print("webrtc_ice_candidate() success\n");
+}
+
+static void _webrtc_add_ice_candidate(connection_s *conn, const gchar *candidate)
+{
+ RET_IF(!conn, "conn is NULL");
+
+ if (conn->is_for_room && candidate) {
+ int ret = webrtc_add_ice_candidate(conn->webrtc, (const char *)candidate);
+ RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+ g_print("webrtc_ice_candidate() success\n");
+ return;
+ }
+
+ g_list_foreach(conn->ice_candidates, __foreach_ice_candidate, NULL);
+
+ g_list_free_full(conn->ice_candidates, free);
+
+ conn->ice_candidates = NULL;
+}
+
static void _webrtc_set_stun_server(int index, char *uri)
{
int ret = 0;
g_print("webrtc_unset_error_cb() success\n");
}
+static void _websocket_connection_send_text_for_room(connection_s *conn, int remote_peer_id, const char *message)
+{
+ gchar *message_for_room;
+
+ RET_IF(!conn, "conn is NULL");
+ RET_IF(!conn->is_for_room, "conn[%p] is not for room", conn);
+ RET_IF(!message, "message is NULL");
+
+ message_for_room = g_strdup_printf ("ROOM_PEER_MSG %d %s", remote_peer_id, message);
+ soup_websocket_connection_send_text(conn->ws_conn, message_for_room);
+ g_free(message_for_room);
+}
+
static void __state_changed_cb(webrtc_h webrtc, webrtc_state_e previous, webrtc_state_e current, void *user_data)
{
- g_print("__state_changed_cb() is invoked, webrtc[%p], prev[%s] -> curr[%s], user_data[%p]\n",
- webrtc, g_webrtc_state_str[previous], g_webrtc_state_str[current], user_data);
+ connection_s *conn = (connection_s *)user_data;
+
+ if (!conn) {
+ g_printerr("__state_changed_cb(), conn is NULL\n");
+ return;
+ }
+
+ g_print("__state_changed_cb() is invoked, webrtc[%p], prev[%s] -> curr[%s], conn[%p]\n",
+ webrtc, g_webrtc_state_str[previous], g_webrtc_state_str[current], conn);
+
+ if (conn->is_for_room && current == WEBRTC_STATE_NEGOTIATING) {
+ if (conn->is_offer) {
+ _webrtc_create_offer(conn);
+ _webrtc_set_local_description(conn, true);
+ _websocket_connection_send_text_for_room(conn, conn->remote_peer_id, conn->offer);
+ } else {
+ if (conn->remote_desc)
+ _webrtc_set_remote_description(conn);
+ if (conn->ice_candidates)
+ _webrtc_add_ice_candidate(conn, NULL);
+ }
+ }
}
static void _webrtc_set_state_changed_cb(int index)
{
int ret = WEBRTC_ERROR_NONE;
- ret = webrtc_set_state_changed_cb(g_conns[index].webrtc, __state_changed_cb, g_conns[index].webrtc);
+ ret = webrtc_set_state_changed_cb(g_conns[index].webrtc, __state_changed_cb, &g_conns[index]);
RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
g_print("webrtc_set_state_changed_cb() success\n");
g_print("webrtc_signaling_request_session() success\n");
}
-static void _webrtc_signaling_send_message(int index, const char *message)
+static void _webrtc_signaling_send_message(connection_s *conn, const char *message)
{
int ret = WEBRTC_ERROR_NONE;
- ret = webrtc_signaling_send_message(g_conns[index].signaling_client, message);
+ RET_IF(!conn, "conn is NULL");
+ RET_IF(!message, "message is NULL");
+
+ ret = webrtc_signaling_send_message(conn->signaling_client, message);
RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
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");
+ connection_s *conn = (connection_s *)user_data;
+
+ g_print("__ice_candidate_cb() is invoked, conn[%p]\n", conn);
+ RET_IF(!conn, "conn is NULL");
g_print("\n[to SERVER > ICE]\n%s\n", 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);
+ if (conn->ws_conn) {
+ if (conn->is_for_room)
+ _websocket_connection_send_text_for_room(conn, conn->remote_peer_id, candidate);
+ else
+ soup_websocket_connection_send_text(conn->ws_conn, candidate);
+ } else if (conn->signaling_client && conn->is_connected) {
+ _webrtc_signaling_send_message(conn, candidate);
+ }
}
static void _webrtc_set_ice_candidate_cb(int index)
{
int ret = WEBRTC_ERROR_NONE;
- ret = webrtc_set_ice_candidate_cb(g_conns[index].webrtc, __ice_candidate_cb, g_conns[index].webrtc);
+ ret = webrtc_set_ice_candidate_cb(g_conns[index].webrtc, __ice_candidate_cb, &g_conns[index]);
RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
g_print("webrtc_set_ice_candidate_cb() success\n");
g_print("__peer_connection_state_change_cb() is invoked, state[%d]\n", state);
}
+static gboolean __idle_cb_for_create_answer_set_local_desc(gpointer user_data)
+{
+ connection_s *conn = (connection_s *)user_data;
+ g_print("__idle_cb_for_create_answer_set_local_desc()\n");
+ _webrtc_create_answer(conn);
+ _webrtc_set_local_description(conn, false);
+ _websocket_connection_send_text_for_room(conn, conn->remote_peer_id, conn->answer);
+
+ return G_SOURCE_REMOVE;
+}
+
static void __signaling_state_change_cb(webrtc_h webrtc, webrtc_signaling_state_e state, void *user_data)
{
+ connection_s *conn = (connection_s *)user_data;
+
g_print("__signaling_state_change_cb() is invoked, state[%d]\n", state);
+
+ if (conn->is_for_room && state == WEBRTC_SIGNALING_STATE_HAVE_REMOTE_OFFER) {
+ g_idle_add(__idle_cb_for_create_answer_set_local_desc, conn);
+ /* FIXME: Commented codes can be enabled if this callback is invoked in main thread. */
+#if 0
+ _webrtc_create_answer(conn);
+ _webrtc_set_local_description(conn, false);
+ _websocket_connection_send_text_for_room(conn, conn->remote_peer_id, conn->answer);
+#endif
+ }
}
static void __ice_gathering_state_change_cb(webrtc_h webrtc, webrtc_ice_gathering_state_e state, void *user_data)
{
int ret = WEBRTC_ERROR_NONE;
- ret = webrtc_set_peer_connection_state_change_cb(g_conns[index].webrtc, __peer_connection_state_change_cb, g_conns[index].webrtc);
+ ret = webrtc_set_peer_connection_state_change_cb(g_conns[index].webrtc, __peer_connection_state_change_cb, &g_conns[index]);
if (ret != WEBRTC_ERROR_NONE)
g_print("failed to webrtc_set_peer_connection_state_change_cb()\n");
else
g_print("webrtc_set_peer_connection_state_change_cb() success\n");
- ret = webrtc_set_signaling_state_change_cb(g_conns[index].webrtc, __signaling_state_change_cb, g_conns[index].webrtc);
+ ret = webrtc_set_signaling_state_change_cb(g_conns[index].webrtc, __signaling_state_change_cb, &g_conns[index]);
if (ret != WEBRTC_ERROR_NONE)
g_print("failed to webrtc_set_signaling_state_change_cb()\n");
else
g_print("webrtc_set_signaling_state_change_cb() success\n");
- ret = webrtc_set_ice_gathering_state_change_cb(g_conns[index].webrtc, __ice_gathering_state_change_cb, g_conns[index].webrtc);
+ ret = webrtc_set_ice_gathering_state_change_cb(g_conns[index].webrtc, __ice_gathering_state_change_cb, &g_conns[index]);
if (ret != WEBRTC_ERROR_NONE)
g_print("failed to webrtc_set_ice_gathering_state_change_cb()\n");
else
g_print("webrtc_set_ice_gathering_state_change_cb() success\n");
- ret = webrtc_set_ice_connection_state_change_cb(g_conns[index].webrtc, __ice_connection_state_change_cb, g_conns[index].webrtc);
+ ret = webrtc_set_ice_connection_state_change_cb(g_conns[index].webrtc, __ice_connection_state_change_cb, &g_conns[index]);
if (ret != WEBRTC_ERROR_NONE)
g_print("failed to webrtc_set_ice_connection_state_change_cb()\n");
else
g_print("webrtc_media_packet_source_unset_buffer_state_changed_cb() success\n");
}
-static void _webrtc_create_offer(int index)
-{
- int ret = WEBRTC_ERROR_NONE;
-
- if (g_conns[index].offer) {
- free(g_conns[index].offer);
- g_conns[index].offer = NULL;
- }
-
- ret = webrtc_create_offer(g_conns[index].webrtc, NULL, &g_conns[index].offer);
- RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-
- g_print("webrtc_create_offer() success\noffer:\n%s\n", g_conns[index].offer);
-}
-
-static void _webrtc_create_answer(int index)
-{
- int ret = WEBRTC_ERROR_NONE;
-
- if (g_conns[index].answer) {
- free(g_conns[index].answer);
- g_conns[index].answer = NULL;
- }
-
- ret = webrtc_create_answer(g_conns[index].webrtc, NULL, &g_conns[index].answer);
- RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-
- g_print("webrtc_create_answer() success\nanswer:\n%s\n", g_conns[index].answer);
-}
-
-static void _webrtc_set_local_description(int index, bool is_offer)
-{
- int ret = WEBRTC_ERROR_NONE;
-
- ret = webrtc_set_local_description(g_conns[index].webrtc, is_offer ? g_conns[index].offer : g_conns[index].answer);
- RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-
- g_print("webrtc_set_local_description() success\n");
-}
-
-static void _webrtc_set_remote_description(int index)
-{
- int ret = WEBRTC_ERROR_NONE;
-
- ret = webrtc_set_remote_description(g_conns[index].webrtc, g_conns[index].remote_desc);
- RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-
- g_print("webrtc_set_remote_description() success\n");
-}
-
-static void __foreach_ice_candidate(gpointer data, gpointer user_data)
-{
- int ret = WEBRTC_ERROR_NONE;
-
- ret = webrtc_add_ice_candidate(g_conns[g_conn_index].webrtc, (const char *)data);
- RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-
- g_print("webrtc_ice_candidate() success\n");
-}
-
-static void _webrtc_add_ice_candidate(int index)
-{
- g_list_foreach(g_conns[index].ice_candidates, __foreach_ice_candidate, NULL);
-
- g_list_free_full(g_conns[index].ice_candidates, free);
-
- g_conns[index].ice_candidates = NULL;
-}
-
static void _webrtc_create_data_channel(int index)
{
int ret = WEBRTC_ERROR_NONE;
}
}
+static void _request_join_room(int index, char *room_name)
+{
+ gchar *msg;
+
+ RET_IF(!room_name, "room_name is NULL");
+
+ if (!g_conns[index].ws_conn && !g_conns[index].is_connected) {
+ g_printerr("server[%s] is not connected\n", g_signaling_server);
+ return;
+ }
+
+ RET_IF(!g_conns[index].ws_conn, "ws_conn is NULL");
+
+ 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("ROOM %s", room_name);
+
+ g_print("\n[to SERVER > %s]\n", msg);
+ soup_websocket_connection_send_text(g_conns[index].ws_conn, msg);
+ g_free(msg);
+}
+
static void _send_local_description(int index, bool is_offer)
{
char *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);
+ _webrtc_signaling_send_message(&g_conns[index], desc);
}
gulong _connect_signal(GObject *obj, const char *signal_name, GCallback callback, gpointer user_data)
__close_websocket(conn);
}
+static void __auto_configure_add_peer(gchar *peer_id, bool is_offer)
+{
+ int i;
+
+ RET_IF(!peer_id, "peer_id is NULL");
+
+ if (!strcmp(peer_id,""))
+ return;
+
+ g_print("add peer[%s] to make an %s\n", peer_id, is_offer ? "offer" : "answer");
+
+ for (i = 0; i < MAX_CONNECTION_LEN; i++) {
+ unsigned int source_id = 0;
+
+ if (g_conns[i].webrtc)
+ continue;
+
+ g_conns[i].remote_peer_id = atoi((const char *)peer_id);
+ g_conns[i].is_for_room = true;
+ g_conns[i].is_offer = is_offer;
+
+ _webrtc_create(i);
+ _webrtc_set_error_cb(i);
+ _webrtc_set_state_changed_cb(i);
+ _webrtc_set_ice_candidate_cb(i);
+ _webrtc_set_negotiation_needed_cb(i);
+ _webrtc_set_all_negotiation_state_change_cbs(i);
+
+ switch (g_conns[i].room_source_type) {
+ case 1:
+ _webrtc_add_media_source(i, WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST + 1, &source_id);
+ _webrtc_media_source_set_video_loopback(i, source_id);
+ _webrtc_add_media_source(i, WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST + 1, NULL);
+ break;
+ case 2:
+ _webrtc_add_media_source(i, WEBRTC_MEDIA_SOURCE_TYPE_CAMERA + 1, &source_id);
+ _webrtc_media_source_set_video_loopback(i, source_id);
+ _webrtc_add_media_source(i, WEBRTC_MEDIA_SOURCE_TYPE_MIC + 1, NULL);
+ break;
+ default:
+ return;
+ }
+
+ _webrtc_start(i);
+ _webrtc_set_track_added_cb(i);
+ _webrtc_set_display_type(i, WEBRTC_DISPLAY_TYPE_EVAS);
+
+ return;
+ }
+ g_printerr("failed to __auto_configure_add_peer_to_offer()\n");
+}
+
+connection_s *__get_conn_from_peer_id(gchar *peer_id, int *index)
+{
+ int i;
+
+ if (!peer_id) {
+ g_printerr("peer_id is NULL\n");
+ return NULL;
+ }
+
+ for (i = 0; i < MAX_CONNECTION_LEN; i++) {
+ if (g_conns[i].remote_peer_id <= 0)
+ continue;
+ if (g_conns[i].remote_peer_id == atoi((const char *)peer_id)) {
+ if (index)
+ *index = i;
+ return &g_conns[i];
+ }
+ }
+
+ g_printerr("not found matching conn from peer_id[%s]", peer_id);
+ return NULL;
+}
+
+static void __auto_configure_release_peer(gchar *peer_id)
+{
+ connection_s *conn;
+ int i;
+
+ RET_IF(!peer_id, "peer_id is NULL");
+
+ g_print("release peer[%s] related resources\n", peer_id);
+
+ if (!(conn = __get_conn_from_peer_id(peer_id, &i)))
+ return;
+
+ _webrtc_stop(i);
+ _webrtc_destroy(i);
+}
+
static void __handle_json_structured_message(connection_s *conn, const gchar *text)
{
JsonNode *root;
free(conn->remote_desc);
conn->remote_desc = strdup(text);
+ if (conn->is_for_room) {
+ webrtc_state_e state = WEBRTC_STATE_IDLE;
+ webrtc_get_state(conn->webrtc, &state);
+ if (state == WEBRTC_STATE_NEGOTIATING)
+ _webrtc_set_remote_description(conn);
+ }
+
} else if (json_object_has_member(object, "ice")){
g_print("\n[from SERVER > ICE]\n%s\n", text);
- conn->ice_candidates = g_list_append(conn->ice_candidates, strdup(text));
+ if (conn->is_for_room) {
+ webrtc_state_e state = WEBRTC_STATE_IDLE;
+ webrtc_get_state(conn->webrtc, &state);
+ if (state == WEBRTC_STATE_NEGOTIATING)
+ _webrtc_add_ice_candidate(conn, text);
+ else
+ conn->ice_candidates = g_list_append(conn->ice_candidates, strdup(text));
+ } else {
+ conn->ice_candidates = g_list_append(conn->ice_candidates, strdup(text));
+ }
} else {
g_printerr("neither 'sdp' nor 'ice' member exist in JSON message [%s]\n", text);
g_object_unref(parser);
}
+static void __auto_configure_handle_room_message(gchar *peer_id, gchar *message)
+{
+ connection_s *conn;
+
+ RET_IF(!peer_id, "peer_id is NULL");
+ RET_IF(!message, "message is NULL");
+
+ g_print("peer[%s], message[%s]\n", peer_id, message);
+
+ if (!(conn = __get_conn_from_peer_id(peer_id, NULL)))
+ return;
+
+ __handle_json_structured_message(conn, message);
+}
+
+static void __handle_room_related_message(connection_s *conn, const gchar *text)
+{
+ gchar **tokens = NULL;
+ guint len;
+ int i;
+
+ RET_IF(!conn, "conn is NULL");
+ RET_IF(!text, "text is NULL");
+
+ if (g_str_has_prefix(text, "ROOM_OK")) {
+ g_print("\n[from SERVER > %s]\n", text);
+ conn->server_status = SERVER_STATUS_ROOM_ESTABLISHED;
+
+ /* parse text, get the previous peers in the room and negotiate to each other */
+ if (strlen(text) > strlen("ROOM_OK")) {
+ /* e.g. ROOM_OK 1234 5311 324 */
+ tokens = g_strsplit(text, " ", 0);
+ len = g_strv_length(tokens);
+ for (i = 1; i < len; i++) {
+ if (i > MAX_CONNECTION_LEN) {
+ g_print("connection[%d], out of range\n", i);
+ break;
+ }
+ __auto_configure_add_peer(tokens[i], true);
+ }
+ }
+
+ } else if (g_str_has_prefix(text, "ROOM_PEER_JOINED")) {
+ g_print("\n[from SERVER > %s]\n", text);
+ /* e.g. ROOM_PEER_JOINED 1234 */
+ tokens = g_strsplit(text, " ", 2);
+ __auto_configure_add_peer(tokens[1], false);
+
+ } else if (g_str_has_prefix(text, "ROOM_PEER_LEFT")) {
+ g_print("\n[from SERVER > %s]\n", text);
+ /* e.g. ROOM_PEER_LEFT 1234 */
+ tokens = g_strsplit(text, " ", 2);
+ __auto_configure_release_peer(tokens[1]);
+
+ } else if (g_str_has_prefix(text, "ROOM_PEER_MSG")) {
+ g_print("\n[from SERVER > %s]\n", text);
+ /* e.g. ROOM_PEER_MSG 1234 msg */
+ tokens = g_strsplit(text, " ", 3);
+ __auto_configure_handle_room_message(tokens[1], tokens[2]);
+
+ } else {
+ g_print("\n[from SERVER > %s]\n", text);
+ conn->server_status = SERVER_STATUS_ERROR_FOUND;
+ }
+
+ if (tokens)
+ g_strfreev(tokens);
+}
+
static void __websocket_message_cb(SoupWebsocketConnection *ws_conn, SoupWebsocketDataType type, GBytes *message, gpointer user_data)
{
gchar *text;
/* NOTE: Logics below can be different in each server */
if (g_strcmp0(text, "HELLO") == 0) {
- g_print("\n[from SERVER > %s] registered done, g_local_peer_id[%d]\n", text, conn->local_peer_id);
+ g_print("\n[from SERVER > %s] registered done, local_peer_id[%d]\n", text, conn->local_peer_id);
} else if (g_strcmp0(text, "SESSION_OK") == 0) {
g_print("\n[from SERVER > %s]\n", text);
conn->server_status = SERVER_STATUS_SESSION_ESTABLISHED;
+ } else if (g_str_has_prefix(text, "ROOM_")) {
+ __handle_room_related_message(conn, text);
+
} else if (g_str_has_prefix(text, "ERROR")) {
g_print("\n[from SERVER > %s]\n", text);
conn->server_status = SERVER_STATUS_ERROR_FOUND;
g_conns[g_conn_index].menu_state = CURRENT_STATUS_MEDIA_PACKET_SOURCE_UNSET_BUFFER_STATE_CHANGED_CB;
} else if (strncmp(cmd, "co", 2) == 0) {
- _webrtc_create_offer(g_conn_index);
+ _webrtc_create_offer(&g_conns[g_conn_index]);
} else if (strncmp(cmd, "ca", 2) == 0) {
- _webrtc_create_answer(g_conn_index);
+ _webrtc_create_answer(&g_conns[g_conn_index]);
} else if (strncmp(cmd, "sl", 2) == 0) {
g_conns[g_conn_index].menu_state = CURRENT_STATUS_SET_LOCAL_DESCRIPTION;
} else if (strncmp(cmd, "sr", 2) == 0) {
- _webrtc_set_remote_description(g_conn_index);
+ _webrtc_set_remote_description(&g_conns[g_conn_index]);
} else if (strncmp(cmd, "st", 2) == 0) {
g_conns[g_conn_index].menu_state = CURRENT_STATUS_SET_STUN_SERVER;
} else if (strncmp(cmd, "rs", 2) == 0) {
g_conns[g_conn_index].menu_state = CURRENT_STATUS_REQUEST_SESSION;
+ } else if (strncmp(cmd, "rj", 2) == 0) {
+ g_conns[g_conn_index].menu_state = CURRENT_STATUS_REQUEST_JOIN_ROOM;
+
} else if (strncmp(cmd, "sd", 2) == 0) {
g_conns[g_conn_index].menu_state = CURRENT_STATUS_SEND_LOCAL_DESCRIPTION;
g_conns[g_conn_index].menu_state = CURRENT_STATUS_SET_MEDIA_PATH_TO_MEDIA_FILE_SOURCE;
} else if (strncmp(cmd, "ac", 2) == 0) {
- _webrtc_add_ice_candidate(g_conn_index);
+ _webrtc_add_ice_candidate(&g_conns[g_conn_index], NULL);
} else {
g_print("unknown menu \n");
g_print(" [*]");
else
g_print(" [ ]");
- g_print("[%d][%s]\n", i, g_server_status_str[g_conns[i].server_status]);
+ g_print("[%d][%s][%d]\n", i, g_server_status_str[g_conns[i].server_status], g_conns[i].local_peer_id);
}
}
g_print("-----------------------------------------------------------------------------------------\n");
g_print("cc. Change connection\n");
g_print("cs. Connect to the signaling server\n");
g_print("rs. Request session of remote peer id\n");
+ g_print("rj. Request join room\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");
} else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_REQUEST_SESSION) {
g_print("*** input remote peer id.\n");
+ } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_REQUEST_JOIN_ROOM) {
+ if (g_conns[g_conn_index].cnt == 0)
+ g_print("*** input source type.(1:videotest/audiotest 2:camera/mic)\n");
+ else if (g_conns[g_conn_index].cnt == 1)
+ g_print("*** input room name to join.\n");
+
} else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_SEND_LOCAL_DESCRIPTION) {
g_print("*** input type of local description to send to the server.(1:offer, 2:answer)\n");
break;
case CURRENT_STATUS_ADD_MEDIA_SOURCE: {
value = atoi(cmd);
- _webrtc_add_media_source(g_conn_index, value);
+ _webrtc_add_media_source(g_conn_index, value, NULL);
reset_menu_state();
break;
}
case CURRENT_STATUS_SET_LOCAL_DESCRIPTION: {
value = atoi(cmd);
if (value == 1)
- _webrtc_set_local_description(g_conn_index, true);
+ _webrtc_set_local_description(&g_conns[g_conn_index], true);
else if (value == 2)
- _webrtc_set_local_description(g_conn_index, false);
+ _webrtc_set_local_description(&g_conns[g_conn_index], false);
else
g_print("invalid value[%d]\n", value);
reset_menu_state();
break;
}
+ case CURRENT_STATUS_REQUEST_JOIN_ROOM: {
+ switch (g_conns[g_conn_index].cnt) {
+ case 0:
+ value = atoi(cmd);
+ if (value <= 0 || value > 2) {
+ g_printerr("invalid value[%d]\n", value);
+ reset_menu_state();
+ break;
+ }
+ g_conns[g_conn_index].room_source_type = value;
+ g_conns[g_conn_index].cnt++;
+ break;
+ case 1:
+ _request_join_room(g_conn_index, cmd);
+ g_conns[g_conn_index].cnt = 0;
+ reset_menu_state();
+ break;
+ }
+ break;
+ }
case CURRENT_STATUS_SEND_LOCAL_DESCRIPTION: {
value = atoi(cmd);
if (value == 1)