webrtc_test: Divide files 10/275010/3
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 12 May 2022 01:04:47 +0000 (10:04 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Mon, 16 May 2022 10:39:46 +0000 (19:39 +0900)
webrtc_test_menu.c regarding menu display is added with
contents extracted from webrtc_test.c.

[Version] 0.3.104
[Issue Type] Refactoring

Change-Id: I691d6cd007a69895d0931a90efd528ffe3227445
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/capi-media-webrtc.spec
test/CMakeLists.txt
test/webrtc_test.c
test/webrtc_test_menu.c [new file with mode: 0644]
test/webrtc_test_priv.h [new file with mode: 0644]

index b836c6a8ce1b238daa11337e272edda286092646..5f07b097d4694e3af9ff95a9cb4a14f5bc83d659 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.103
+Version:    0.3.104
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 4b8fda295226a6527a821579ea3529c628a4ec4b..df544ca518d02cb51e1fc177872b548fee8965a8 100644 (file)
@@ -1,5 +1,6 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 SET(fw_test "${fw_name}-test")
+SET(test_name "webrtc_test")
 
 INCLUDE_DIRECTORIES(../include)
 
@@ -21,8 +22,9 @@ aux_source_directory(. sources)
 
 FOREACH(src ${sources})
     GET_FILENAME_COMPONENT(src_name ${src} NAME_WE)
+    LIST(APPEND src_list "${src_name}")
     MESSAGE("${src_name}")
-    ADD_EXECUTABLE(${src_name} ${src})
-    TARGET_LINK_LIBRARIES(${src_name} capi-media-webrtc ${${fw_test}_LDFLAGS})
 ENDFOREACH()
+ADD_EXECUTABLE(${test_name} ${src_list})
+TARGET_LINK_LIBRARIES(${test_name} capi-media-webrtc ${${fw_test}_LDFLAGS})
 
index f8a2cb35ea62c4571e74bb71c0c537ee1badc37f..22b1041f6598908957f5526b87aa9681fdbd0fda 100644 (file)
 * limitations under the License.
 */
 
-#include <webrtc_internal.h>
-#include <media_format.h>
-#include <media_packet_internal.h>
-#include <sound_manager.h>
-#ifndef TIZEN_TV
-#include <esplusplayer_capi.h>
-#endif
-#include <appcore-efl.h>
-#include <Elementary.h>
+#include "webrtc_test_priv.h"
+
 #include <tbm_surface_internal.h>
-#include <glib.h>
-#include <gst/gst.h>
-#include <libsoup/soup.h>
 #include <json-glib/json-glib.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #endif
 #define PACKAGE "webrtc_test"
 
-//#define __DEBUG_VALIDATE_MEDIA_PACKET_SOURCE__
-//#define __DEBUG_VALIDATE_ENCODED_FRAME_CB__
-
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
 #define LOG_TAG "WEBRTC_TEST"
 
-#define RET_IF(expr, fmt, arg...) \
-do { \
-       if ((expr)) { \
-               g_printerr("failed to %s(), "fmt"\n", __func__, ##arg); \
-               return; \
-       } \
-} while (0)
-
-#define MAX_STRING_LEN 512
-#define MAX_CHANNEL_LEN 10
-#define MAX_CONNECTION_LEN 3
-#define MAX_MEDIA_PACKET_SOURCE_LEN 4
 #define MAX_EXPECTED_SIZE 1024 * 1024 * 1024
 #define USE_GSTBUFFER_WITHOUT_COPY true
 #define FONT_SIZE 30
 
-#define TEST_MENU_WEBRTC_COMMON         0x00001000
-#define TEST_MENU_WEBRTC_MEDIA_SOURCE   0x00002000
-#define TEST_MENU_WEBRTC_MEDIA_RENDER   0x00004000
-#define TEST_MENU_WEBRTC_DATA_CHANNEL   0x00008000
-#define TEST_MENU_WEBRTC_STATS          0x00010000
-#define TEST_MENU_APP_SIGNALING         0x00020000
-
-enum {
-       CURRENT_STATUS_MAINMENU,
-       CURRENT_STATUS_TERMINATE,
-       CURRENT_STATUS_QUIT,
-       /* webrtc common */
-       CURRENT_STATUS_CREATE = TEST_MENU_WEBRTC_COMMON | 0x01,
-       CURRENT_STATUS_START = TEST_MENU_WEBRTC_COMMON | 0x02,
-       CURRENT_STATUS_STOP = TEST_MENU_WEBRTC_COMMON | 0x03,
-       CURRENT_STATUS_DESTROY = TEST_MENU_WEBRTC_COMMON | 0x04,
-       CURRENT_STATUS_GET_STATE = TEST_MENU_WEBRTC_COMMON | 0x05,
-       CURRENT_STATUS_SET_STUN_SERVER = TEST_MENU_WEBRTC_COMMON | 0x06,
-       CURRENT_STATUS_GET_STUN_SERVER = TEST_MENU_WEBRTC_COMMON | 0x07,
-       CURRENT_STATUS_ADD_TURN_SERVER = TEST_MENU_WEBRTC_COMMON | 0x08,
-       CURRENT_STATUS_GET_TURN_SERVERS = TEST_MENU_WEBRTC_COMMON | 0x09,
-       CURRENT_STATUS_SET_BUNDLE_POLICY = TEST_MENU_WEBRTC_COMMON | 0x0A,
-       CURRENT_STATUS_GET_BUNDLE_POLICY = TEST_MENU_WEBRTC_COMMON | 0x0B,
-       CURRENT_STATUS_SET_ICE_TRANSPORT_POLICY = TEST_MENU_WEBRTC_COMMON | 0x0C,
-       CURRENT_STATUS_GET_ICE_TRANSPORT_POLICY = TEST_MENU_WEBRTC_COMMON | 0x0D,
-       CURRENT_STATUS_CREATE_OFFER = TEST_MENU_WEBRTC_COMMON | 0x0E,
-       CURRENT_STATUS_CREATE_ANSWER = TEST_MENU_WEBRTC_COMMON | 0x0F,
-       CURRENT_STATUS_CREATE_OFFER_ASYNC = TEST_MENU_WEBRTC_COMMON | 0x10,
-       CURRENT_STATUS_CREATE_ANSWER_ASYNC = TEST_MENU_WEBRTC_COMMON | 0x11,
-       CURRENT_STATUS_SET_LOCAL_DESCRIPTION = TEST_MENU_WEBRTC_COMMON | 0x12,
-       CURRENT_STATUS_SET_REMOTE_DESCRIPTION = TEST_MENU_WEBRTC_COMMON | 0x13,
-       CURRENT_STATUS_ADD_ICE_CANDIDATE = TEST_MENU_WEBRTC_COMMON | 0x14,
-       CURRENT_STATUS_SET_ALL_CALLBACKS = TEST_MENU_WEBRTC_COMMON | 0x15,
-       CURRENT_STATUS_UNSET_ALL_CALLBACKS = TEST_MENU_WEBRTC_COMMON | 0x16,
-       CURRENT_STATUS_GET_ALL_NEGOTIATION_STATES = TEST_MENU_WEBRTC_COMMON | 0x17,
-       CURRENT_STATUS_SET_RTP_PACKET_DROP_PROBABILITY = TEST_MENU_WEBRTC_COMMON | 0x18,
-       CURRENT_STATUS_GET_RTP_PACKET_DROP_PROBABILITY = TEST_MENU_WEBRTC_COMMON | 0x19,
-       /* webrtc media source */
-       CURRENT_STATUS_ADD_MEDIA_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x01,
-       CURRENT_STATUS_REMOVE_MEDIA_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x02,
-       CURRENT_STATUS_MEDIA_SOURCE_SET_TRANSCEIVER_DIRECTION = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x03,
-       CURRENT_STATUS_MEDIA_SOURCE_GET_TRANSCEIVER_DIRECTION = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x04,
-       CURRENT_STATUS_MEDIA_SOURCE_SET_PAUSE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x05,
-       CURRENT_STATUS_MEDIA_SOURCE_GET_PAUSE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x06,
-       CURRENT_STATUS_MEDIA_SOURCE_SET_MUTE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x07,
-       CURRENT_STATUS_MEDIA_SOURCE_GET_MUTE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x08,
-       CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_RESOLUTION = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x09,
-       CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_RESOLUTION = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0A,
-       CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_FRAMERATE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0B,
-       CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_FRAMERATE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0C,
-       CURRENT_STATUS_FILE_SOURCE_SET_PATH = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0D,
-       CURRENT_STATUS_FILE_SOURCE_SET_LOOPING = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0E,
-       CURRENT_STATUS_FILE_SOURCE_GET_LOOPING = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0F,
-       CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_FORMAT = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x10,
-       CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_BUFFER_STATE_CHANGED_CB = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x11,
-       CURRENT_STATUS_MEDIA_PACKET_SOURCE_UNSET_BUFFER_STATE_CHANGED_CB = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x12,
-       CURRENT_STATUS_START_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x13,
-       CURRENT_STATUS_STOP_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x14,
-       CURRENT_STATUS_SET_CROP_SCREEN_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x15,
-       CURRENT_STATUS_UNSET_CROP_SCREEN_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x16,
-       /* webrtc media render */
-       CURRENT_STATUS_SET_DISPLAY_TYPE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x01,
-       CURRENT_STATUS_SET_DISPLAY_MODE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x02,
-       CURRENT_STATUS_GET_DISPLAY_MODE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x03,
-       CURRENT_STATUS_SET_DISPLAY_VISIBLE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x04,
-       CURRENT_STATUS_GET_DISPLAY_VISIBLE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x05,
-       CURRENT_STATUS_SET_ENCODED_AUDIO_FRAME_CB = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x06,
-       CURRENT_STATUS_UNSET_ENCODED_AUDIO_FRAME_CB = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x07,
-       CURRENT_STATUS_SET_ENCODED_VIDEO_FRAME_CB = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x08,
-       CURRENT_STATUS_UNSET_ENCODED_VIDEO_FRAME_CB = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x09,
-       CURRENT_STATUS_MEDIA_SOURCE_SET_AUDIO_LOOPBACK = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x0A,
-       CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x0B,
-       CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_LOOPBACK = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x0C,
-       CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x0D,
-       /* webrtc data channel */
-       CURRENT_STATUS_DATA_CHANNEL_CREATE = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x01,
-       CURRENT_STATUS_DATA_CHANNEL_DESTROY = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x02,
-       CURRENT_STATUS_DATA_CHANNEL_GET_LABEL = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x03,
-       CURRENT_STATUS_DATA_CHANNEL_SEND_STRING = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x04,
-       CURRENT_STATUS_DATA_CHANNEL_SEND_STRING_AS_BYTES = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x05,
-       CURRENT_STATUS_DATA_CHANNEL_SEND_FILE = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x06,
-       CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x07,
-       CURRENT_STATUS_DATA_CHANNEL_UNSET_BUFFERED_AMOUNT_LOW_CB = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x08,
-       CURRENT_STATUS_DATA_CHANNEL_GET_BUFFERED_AMOUNT_LOW_THRESHOLD = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x09,
-       CURRENT_STATUS_DATA_CHANNEL_GET_BUFFERED_AMOUNT = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x0A,
-       /* webrtc stats */
-       CURRENT_STATUS_FOREACH_STATS = TEST_MENU_WEBRTC_STATS | 0x01,
-       /* app. setting & signaling */
-       CURRENT_STATUS_SETTING_SIGNALING_SERVER = TEST_MENU_APP_SIGNALING | 0x01,
-       CURRENT_STATUS_CONNECT_SIGNALING_SERVER = TEST_MENU_APP_SIGNALING | 0x02,
-       CURRENT_STATUS_SETTING_PROXY = TEST_MENU_APP_SIGNALING | 0x03,
-       CURRENT_STATUS_REQUEST_SESSION = TEST_MENU_APP_SIGNALING | 0x04,
-       CURRENT_STATUS_REQUEST_JOIN_ROOM = TEST_MENU_APP_SIGNALING | 0x05,
-       CURRENT_STATUS_SEND_LOCAL_DESCRIPTION = TEST_MENU_APP_SIGNALING | 0x06,
-       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CREATE = TEST_MENU_APP_SIGNALING | 0x07,
-       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_DESTROY = TEST_MENU_APP_SIGNALING | 0x08,
-       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_START = TEST_MENU_APP_SIGNALING | 0x09,
-       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_STOP = TEST_MENU_APP_SIGNALING | 0x0A,
-       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CONNECT = TEST_MENU_APP_SIGNALING | 0x0B,
-       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_DISCONNECT = TEST_MENU_APP_SIGNALING | 0x0C,
-};
-
-typedef struct {
-       const char *cmd;
-       int status;
-       bool key_input_needed;
-} menu_info_s;
-
-menu_info_s g_menu_infos[] = {
-       { "none", CURRENT_STATUS_MAINMENU, false },
-       { "none", CURRENT_STATUS_TERMINATE, false },
-       { "q", CURRENT_STATUS_QUIT, false },
-       /* webrtc common */
-       { "c", CURRENT_STATUS_CREATE, false },
-       { "s", CURRENT_STATUS_START, false },
-       { "t", CURRENT_STATUS_STOP, false },
-       { "d", CURRENT_STATUS_DESTROY, false },
-       { "g", CURRENT_STATUS_GET_STATE, false },
-       { "st", CURRENT_STATUS_SET_STUN_SERVER, true },
-       { "gt", CURRENT_STATUS_GET_STUN_SERVER, false },
-       { "su", CURRENT_STATUS_ADD_TURN_SERVER, true },
-       { "gu", CURRENT_STATUS_GET_TURN_SERVERS, false },
-       { "sbp", CURRENT_STATUS_SET_BUNDLE_POLICY, true },
-       { "gbp", CURRENT_STATUS_GET_BUNDLE_POLICY, false },
-       { "stp", CURRENT_STATUS_SET_ICE_TRANSPORT_POLICY, true },
-       { "gtp", CURRENT_STATUS_GET_ICE_TRANSPORT_POLICY, false },
-       { "co", CURRENT_STATUS_CREATE_OFFER, false },
-       { "ca", CURRENT_STATUS_CREATE_ANSWER, false },
-       { "coa", CURRENT_STATUS_CREATE_OFFER_ASYNC, false },
-       { "caa", CURRENT_STATUS_CREATE_ANSWER_ASYNC, false },
-       { "sl", CURRENT_STATUS_SET_LOCAL_DESCRIPTION, true },
-       { "sr", CURRENT_STATUS_SET_REMOTE_DESCRIPTION, false },
-       { "ac", CURRENT_STATUS_ADD_ICE_CANDIDATE, false },
-       { "sac", CURRENT_STATUS_SET_ALL_CALLBACKS, false },
-       { "uac", CURRENT_STATUS_UNSET_ALL_CALLBACKS, false },
-       { "gan", CURRENT_STATUS_GET_ALL_NEGOTIATION_STATES, false },
-       { "sdp", CURRENT_STATUS_SET_RTP_PACKET_DROP_PROBABILITY, true },
-       { "gdp", CURRENT_STATUS_GET_RTP_PACKET_DROP_PROBABILITY, true },
-       /* webrtc media source */
-       { "a", CURRENT_STATUS_ADD_MEDIA_SOURCE, true },
-       { "r", CURRENT_STATUS_REMOVE_MEDIA_SOURCE, true },
-       { "td", CURRENT_STATUS_MEDIA_SOURCE_SET_TRANSCEIVER_DIRECTION, true },
-       { "gd", CURRENT_STATUS_MEDIA_SOURCE_GET_TRANSCEIVER_DIRECTION, true },
-       { "p", CURRENT_STATUS_MEDIA_SOURCE_SET_PAUSE, true },
-       { "o", CURRENT_STATUS_MEDIA_SOURCE_GET_PAUSE, true },
-       { "mu", CURRENT_STATUS_MEDIA_SOURCE_SET_MUTE, true },
-       { "mg", CURRENT_STATUS_MEDIA_SOURCE_GET_MUTE, true },
-       { "v", CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_RESOLUTION, true },
-       { "l", CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_RESOLUTION, true },
-       { "f", CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_FRAMERATE, true },
-       { "m", CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_FRAMERATE, true },
-       { "pa", CURRENT_STATUS_FILE_SOURCE_SET_PATH, true },
-       { "sfl", CURRENT_STATUS_FILE_SOURCE_SET_LOOPING, true },
-       { "gfl", CURRENT_STATUS_FILE_SOURCE_GET_LOOPING, true },
-       { "sf", CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_FORMAT, true },
-       { "sm", CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_BUFFER_STATE_CHANGED_CB, true },
-       { "um", CURRENT_STATUS_MEDIA_PACKET_SOURCE_UNSET_BUFFER_STATE_CHANGED_CB, true },
-       { "sp", CURRENT_STATUS_START_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE, true },
-       { "tp", CURRENT_STATUS_STOP_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE, true },
-       { "scs", CURRENT_STATUS_SET_CROP_SCREEN_SOURCE, true },
-       { "ucs", CURRENT_STATUS_UNSET_CROP_SCREEN_SOURCE, true },
-       /* webrtc media render */
-       { "dt", CURRENT_STATUS_SET_DISPLAY_TYPE, true },
-       { "dm", CURRENT_STATUS_SET_DISPLAY_MODE, true },
-       { "gm", CURRENT_STATUS_GET_DISPLAY_MODE, true },
-       { "dv", CURRENT_STATUS_SET_DISPLAY_VISIBLE, true },
-       { "gv", CURRENT_STATUS_GET_DISPLAY_VISIBLE, true },
-       { "sa", CURRENT_STATUS_SET_ENCODED_AUDIO_FRAME_CB, false },
-       { "ua", CURRENT_STATUS_UNSET_ENCODED_AUDIO_FRAME_CB, false },
-       { "sv", CURRENT_STATUS_SET_ENCODED_VIDEO_FRAME_CB, false },
-       { "uv", CURRENT_STATUS_UNSET_ENCODED_VIDEO_FRAME_CB, false },
-       { "al", CURRENT_STATUS_MEDIA_SOURCE_SET_AUDIO_LOOPBACK, true },
-       { "ual", CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK, true },
-       { "vl", CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_LOOPBACK, true },
-       { "uvl", CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK, true },
-       /* webrtc data channel */
-       { "cd", CURRENT_STATUS_DATA_CHANNEL_CREATE, false },
-       { "dd", CURRENT_STATUS_DATA_CHANNEL_DESTROY, false },
-       { "dl", CURRENT_STATUS_DATA_CHANNEL_GET_LABEL, false },
-       { "zs", CURRENT_STATUS_DATA_CHANNEL_SEND_STRING, true },
-       { "zb", CURRENT_STATUS_DATA_CHANNEL_SEND_STRING_AS_BYTES, true },
-       { "zf", CURRENT_STATUS_DATA_CHANNEL_SEND_FILE, true },
-       { "sbc", CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB, true },
-       { "ubc", CURRENT_STATUS_DATA_CHANNEL_UNSET_BUFFERED_AMOUNT_LOW_CB, false },
-       { "gbt", CURRENT_STATUS_DATA_CHANNEL_GET_BUFFERED_AMOUNT_LOW_THRESHOLD, false },
-       { "ba", CURRENT_STATUS_DATA_CHANNEL_GET_BUFFERED_AMOUNT, false },
-       /* webrtc stats */
-       { "sts", CURRENT_STATUS_FOREACH_STATS, true },
-       /* app. setting & signaling */
-       { "ss", CURRENT_STATUS_SETTING_SIGNALING_SERVER, true },
-       { "cs", CURRENT_STATUS_CONNECT_SIGNALING_SERVER, false },
-       { "px", CURRENT_STATUS_SETTING_PROXY, true },
-       { "rs", CURRENT_STATUS_REQUEST_SESSION, true },
-       { "rj", CURRENT_STATUS_REQUEST_JOIN_ROOM, true },
-       { "sd", CURRENT_STATUS_SEND_LOCAL_DESCRIPTION, true },
-       { "ssc", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CREATE, true },
-       { "ssd", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_DESTROY, false },
-       { "sss", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_START, false },
-       { "sst", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_STOP, false },
-       { "scc", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CONNECT, true },
-       { "scd", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_DISCONNECT, false },
-       { NULL, -1, false },
-};
-
-enum {
-       SERVER_STATUS_DISCONNECTED,
-       SERVER_STATUS_CONNECTED,
-       SERVER_STATUS_SESSION_ESTABLISHED,
-       SERVER_STATUS_SESSION_CLOSED,
-       SERVER_STATUS_ROOM_ESTABLISHED,
-       SERVER_STATUS_ERROR_FOUND
-};
-
 const char *g_server_status_str[] = {
        [SERVER_STATUS_DISCONNECTED] = "DISCONNECTED",
        [SERVER_STATUS_CONNECTED] = "CONNECTED",
@@ -283,7 +45,7 @@ const char *g_server_status_str[] = {
        [SERVER_STATUS_ERROR_FOUND] = "ERROR_FOUND",
 };
 
-static const char *g_webrtc_state_str[] = {
+const char *g_webrtc_state_str[] = {
        [WEBRTC_STATE_IDLE] = "IDLE",
        [WEBRTC_STATE_NEGOTIATING] = "NEGOTIATING",
        [WEBRTC_STATE_PLAYING] = "PLAYING",
@@ -308,116 +70,19 @@ static const char *g_webrtc_stats_type_str[] = {
        [WEBRTC_STATS_TYPE_REMOTE_OUTBOUND_RTP] = "remote-outbound-rtp",
 };
 
+int g_menu_status;
+int g_cnt;
+gchar g_proxy[MAX_STRING_LEN];
+appdata_s g_ad;
+connection_s g_conns[MAX_CONNECTION_LEN];
+signaling_server_s g_signaling_server;
+static webrtc_signaling_server_h g_inner_signaling_server;
+
 /* for video display */
 static Evas_Object *g_win_id;
 static Evas_Object *g_eo_mine;
 static Evas_Object *g_text_eo_mine;
 
-typedef struct {
-       GHashTable *menu_items;
-       Evas_Object *win;
-       int win_width;
-       int win_height;
-} appdata_s;
-
-typedef struct {
-       unsigned int source_id;
-       media_format_h format;
-
-       webrtc_h webrtc;
-       GstElement *src_pipeline;
-#ifdef __DEBUG_VALIDATE_MEDIA_PACKET_SOURCE__
-       GstElement *render_pipeline;
-       GstElement *appsrc;
-#endif
-       GstElement *src;
-       GstElement *sink;
-       GstElement *demux;
-       GstBus *bus;
-       guint bus_watcher;
-       gulong handoff_signal_id;
-       gulong pad_added_signal_id;
-       bool is_overflowed;
-       bool is_stop_requested;
-       GCond cond;
-       GMutex mutex;
-       bool got_eos;
-} media_packet_source_s;
-
-typedef struct _connection_s {
-       int index;
-       int remote_peer_id;
-
-       bool is_for_room;
-       bool is_offer;
-       int room_source_type;
-
-       webrtc_h webrtc;
-       webrtc_data_channel_h channels[MAX_CHANNEL_LEN];
-       int channel_index;
-       webrtc_data_channel_h recv_channels[MAX_CHANNEL_LEN];
-       char *offer;
-       char *answer;
-       char *remote_desc;
-       GList *ice_candidates;
-
-       /* receive data & dump file */
-       gint64 sum_size;
-       gchar *expected_name;
-       gint64 expected_size;
-       char* receive_buffer;
-
-       struct {
-               sound_stream_info_h stream_info;
-       } source;
-
-       struct {
-               sound_stream_info_h stream_info;
-               webrtc_display_type_e display_type;
-               Evas_Object *eo;
-               Evas_Object *text_eo;
-               unsigned int loopback_track_id;
-#ifndef TIZEN_TV
-               esplusplayer_handle espp;
-#endif
-       } render;
-
-#ifndef TIZEN_TV
-       bool encoded_video_frame_cb_is_set;
-       bool encoded_audio_frame_cb_is_set;
-#endif
-#ifdef __DEBUG_VALIDATE_ENCODED_FRAME_CB__
-       GstElement *audio_render_pipeline;
-       GstElement *video_render_pipeline;
-       GstElement *appsrc_for_audio;
-       GstElement *appsrc_for_video;
-#endif
-       media_packet_source_s packet_sources[MAX_MEDIA_PACKET_SOURCE_LEN];
-} connection_s;
-
-typedef struct _signaling_server_s {
-       gchar url[MAX_STRING_LEN];
-       SoupWebsocketConnection *ws_conn;
-       int server_status;
-       gint32 local_peer_id;
-
-       /* for private network - internal API */
-       webrtc_signaling_client_h signaling_client;
-       char *private_ip;
-       int port;
-       bool is_connected;
-} signaling_server_s;
-
-static gchar g_proxy[MAX_STRING_LEN];
-
-static appdata_s g_ad;
-static connection_s g_conns[MAX_CONNECTION_LEN];
-static signaling_server_s g_signaling_server;
-static int g_menu_status;
-static int g_cnt;
-
-static webrtc_signaling_server_h g_inner_signaling_server;
-
 #if defined(__DEBUG_VALIDATE_MEDIA_PACKET_SOURCE__) || defined(__DEBUG_VALIDATE_ENCODED_FRAME_CB__)
 GstBuffer *__alloc_buffer_from_packet(media_packet_h packet);
 #endif
@@ -1620,7 +1285,7 @@ static void _webrtc_add_turn_server(int index, char *uri)
        g_print("webrtc_add_turn_server() success, uri[%s]\n", uri);
 }
 
-static bool __foreach_turn_server(const char *turn_server, gpointer user_data)
+bool foreach_turn_server(const char *turn_server, gpointer user_data)
 {
        g_print("- turn server %s\n", turn_server);
        return true;
@@ -1630,7 +1295,7 @@ static void _webrtc_get_turn_servers(int index)
 {
        int ret = 0;
 
-       ret = webrtc_foreach_turn_server(g_conns[index].webrtc, __foreach_turn_server, NULL);
+       ret = webrtc_foreach_turn_server(g_conns[index].webrtc, foreach_turn_server, NULL);
        RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
 
        g_print("webrtc_foreach_turn_server() success\n");
@@ -4378,7 +4043,7 @@ static void _webrtc_signaling_server_stop(void)
        g_print("webrtc_signaling_server_stop() success\n");
 }
 
-static void quit_program()
+void quit_program(void)
 {
        int i;
        for (i = 0; i < MAX_CONNECTION_LEN; i++) {
@@ -4421,460 +4086,12 @@ static bool interpret_main_menu_cmd(char *cmd)
        return true;
 }
 
-static void display_handle_status(int index)
-{
-       int ret = WEBRTC_ERROR_NONE;
-       webrtc_state_e state;
-       char *stun_server = NULL;
-
-       if (g_conns[index].webrtc == NULL)
-               return;
-
-       ret = webrtc_get_state(g_conns[index].webrtc, &state);
-       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-
-       ret = webrtc_get_stun_server(g_conns[index].webrtc, &stun_server);
-       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-
-       ret = webrtc_foreach_turn_server(g_conns[index].webrtc, __foreach_turn_server, NULL);
-       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
-
-       g_print("  webrtc[%p]", g_conns[index].webrtc);
-       g_print("  state[%s]", g_webrtc_state_str[state]);
-       if (stun_server) {
-               g_print("  STUN server[%s]", stun_server);
-               free(stun_server);
-       }
-
-       g_print("\n-----------------------------------------------------------------------------------------\n");
-}
-
-static void display_setting_status(void)
-{
-       int len_proxy = strlen(g_proxy);
-       int len_server = strlen(g_signaling_server.url);
-       int i;
-
-       if (len_proxy > 0)
-               g_print("  proxy[%s]", g_proxy);
-       if (len_server > 0)
-               g_print("  server[%s][%s]\n", g_signaling_server.url, g_server_status_str[g_signaling_server.server_status]);
-       if (g_signaling_server.private_ip && g_signaling_server.port > 0)
-               g_print("  server[%s:%d][%s]\n", g_signaling_server.private_ip, g_signaling_server.port, g_server_status_str[g_signaling_server.server_status]);
-       if (g_signaling_server.local_peer_id > 0)
-               g_print("  local peer id : %d\n", g_signaling_server.local_peer_id);
-       for (i = 0; i < MAX_CONNECTION_LEN; i++) {
-               if (g_conns[i].remote_peer_id == 0)
-                       continue;
-               g_print("  [%d] remote peer id : %d\n", i, g_conns[i].remote_peer_id);
-       }
-       g_print("-----------------------------------------------------------------------------------------\n");
-}
-
-static void display_menu_main(void)
-{
-       g_print("\n");
-       g_print("=========================================================================================\n");
-       g_print("                   Native WebRTC Test (press q to quit, * for internal API)\n");
-       g_print("-----------------------------------------------------------------------------------------\n");
-       display_handle_status(0);
-       g_print("c. Create\t");
-       g_print("d. Destroy\t");
-       g_print("s. Start\t");
-       g_print("t. Stop\t\t");
-       g_print("g. Get state\n");
-       g_print("sac. Set all callbacks\t");
-       g_print("uac. Unset all callbacks\n");
-       g_print("gan. Gets all the negotiation states\n");
-       g_print("st. Set STUN server\t");
-       g_print("gt. Get STUN server\t");
-       g_print("su. Add TURN server\t");
-       g_print("gu. Get TURN servers\n");
-       g_print("sbp. Set bundle policy\t");
-       g_print("gbp. Get bundle policy\n");
-       g_print("stp. Set ICE transport policy\t");
-       g_print("gtp. Get ICE transport policy\n");
-       g_print("co. Create offer\t");
-       g_print("ca. Create answer\n");
-       g_print("coa. Create offer(async)\t");
-       g_print("caa. Create answer(async)\n");
-       g_print("sl. Set local description\t");
-       g_print("sr. Set remote description\n");
-       g_print("ac. Add ICE candidate\n");
-       g_print("sdp. *Set RTP packet drop probability\t");
-       g_print("gdp. *Get RTP packet drop probability\n");
-       g_print("------------------------------------- Media Source --------------------------------------\n");
-       g_print("a. Add media source\t");
-       g_print("r. Remove media source\n");
-       g_print("p. Pause/play media source\t");
-       g_print("o. Get the media source pause\n");
-       g_print("mu. Mute/unmute media source\t");
-       g_print("mg. Get the media source mute\n");
-       g_print("v. Set video resolution\t");
-       g_print("l. Get video resolution\n");
-       g_print("f. Set video framerate\t");
-       g_print("m. Get video framerate\n");
-       g_print("td. Set transceiver direction\t");
-       g_print("gd. Get transceiver direction\n");
-       g_print("pa. Set media path to file source\n");
-       g_print("sfl. Set file source looping\t");
-       g_print("gfl. Set file source looping\n");
-       g_print("sf. Set media format to media packet source\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("scs. *Set crop screen source\t");
-       g_print("ucs. *Unset crop screen source\n");
-       g_print("------------------------------------- Media Render --------------------------------------\n");
-       g_print("dt. Set display type\t");
-       g_print("dm. Set display mode\t");
-       g_print("gm. Get display mode\n");
-       g_print("dv. Set display visible\t");
-       g_print("gv. Get display visible\n");
-       g_print("al. Set audio loopback\t");
-       g_print("ual. Unset audio loopback\n");
-       g_print("vl. Set video loopback\t");
-       g_print("uvl. Unset video loopback\n");
-       g_print("sa. Set encoded audio frame callback\t");
-       g_print("ua. Unset encoded audio frame callback\n");
-       g_print("sv. Set encoded video frame callback\t");
-       g_print("uv. Unset encoded video frame callback\n");
-       g_print("------------------------------------- Data Channel --------------------------------------\n");
-       g_print("cd. Create data channel\t");
-       g_print("dd. Destroy data channel\n");
-       g_print("dl. Get data channel label\n");
-       g_print("zs. Send string via data channel\n");
-       g_print("zb. Send string as bytes data via data channel\t");
-       g_print("zf. Send file via data channel\n");
-       g_print("ba. Get buffered amount\n");
-       g_print("sbc. Set buffered amount low callback\t");
-       g_print("ubc. Unset buffered amount low callback\n");
-       g_print("gbt. Get buffered amount low threshold\n");
-       g_print("---------------------------------------- Stats ------------------------------------------\n");
-       g_print("sts. Get stats\n");
-       g_print("------------------------------- App. Setting & Signaling --------------------------------\n");
-       display_setting_status();
-       g_print("px. Set proxy URL\n");
-       g_print("ss. Set signaling server URL\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("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");
-       g_print(" >>> ");
-}
-
-static void display_menu_webrtc_common(void)
-{
-       switch (g_menu_status) {
-       case CURRENT_STATUS_SET_STUN_SERVER:
-               g_print("*** input STUN server address.\n");
-               break;
-       case CURRENT_STATUS_ADD_TURN_SERVER:
-               g_print("*** input TURN server address.\n");
-               break;
-       case CURRENT_STATUS_SET_BUNDLE_POLICY:
-               g_print("*** input bundle policy.(0:none, 1:max-bundle)\n");
-               break;
-       case CURRENT_STATUS_SET_ICE_TRANSPORT_POLICY:
-               g_print("*** input ICE transport policy.(0:all, 1:relay)\n");
-               break;
-       case CURRENT_STATUS_SET_LOCAL_DESCRIPTION:
-               g_print("*** input type of local description.(1:offer, 2:answer)\n");
-               break;
-       case CURRENT_STATUS_SET_RTP_PACKET_DROP_PROBABILITY:
-               if (g_cnt == 0)
-                       g_print("*** input side.(1:sender, 2:receiver)\n");
-               else if (g_cnt == 1)
-                       g_print("*** input drop probability.(0 ~ 1.0)\n");
-               break;
-       case CURRENT_STATUS_GET_RTP_PACKET_DROP_PROBABILITY:
-               if (g_cnt == 0)
-                       g_print("*** input side.(1:sender, 2:receiver)\n");
-               break;
-       }
-       g_print(" >>> ");
-}
-
-static void display_menu_webrtc_media_source(void)
-{
-       switch (g_menu_status) {
-       case CURRENT_STATUS_ADD_MEDIA_SOURCE:
-               g_print("*** input media source type.(1:audiotest, 2:videotest, 3:mic, 4:camera, 5:screen, 6:file, 7:media packet, 8:custom audio, 9:custom video)\n");
-               break;
-       case CURRENT_STATUS_REMOVE_MEDIA_SOURCE:
-               g_print("*** input media source id to remove.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_SET_PAUSE:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input media type.(1:audio 2:video)\n");
-               else if (g_cnt == 2)
-                       g_print("*** input pause or play.(1:pause, 0:play)\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_GET_PAUSE :
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input media type.(1:audio 2:video)\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_SET_MUTE:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input media type.(1:audio 2:video)\n");
-               else if (g_cnt == 2)
-                       g_print("*** input mute mode.(1:mute 0:unmute)\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_GET_MUTE:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input media type.(1:audio 2:video)\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_RESOLUTION:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input width.\n");
-               else if (g_cnt == 2)
-                       g_print("*** input height.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_RESOLUTION:
-               g_print("*** input source id.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_FRAMERATE:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input framerate.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_FRAMERATE:
-               g_print("*** input source id.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_SET_TRANSCEIVER_DIRECTION:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input media type.(1:audio 2:video)\n");
-               else if (g_cnt == 2)
-                       g_print("*** input transceiver direction.(1:sendonly 2:recvonly 3:sendrecv)\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_GET_TRANSCEIVER_DIRECTION:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input media type.(1:audio 2:video)\n");
-               break;
-       case CURRENT_STATUS_FILE_SOURCE_SET_PATH:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input media path.\n");
-               break;
-       case CURRENT_STATUS_FILE_SOURCE_SET_LOOPING:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input looping state.(1:true 0:false)\n");
-               break;
-       case CURRENT_STATUS_FILE_SOURCE_GET_LOOPING:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_BUFFER_STATE_CHANGED_CB:
-               g_print("*** input media packet source id to set buffer state changed callback.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_PACKET_SOURCE_UNSET_BUFFER_STATE_CHANGED_CB:
-               g_print("*** input media packet source id to unset buffer state changed callback.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_FORMAT:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input media format.(1:I420 2:NV12 3:PCM_S16LE 4:H264)\n");
-               break;
-       case CURRENT_STATUS_START_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE:
-               g_print("*** input media packet source id to start pushing packet.\n");
-               break;
-       case CURRENT_STATUS_STOP_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE:
-               g_print("*** input media packet source id to stop pushing packet.\n");
-               break;
-       case CURRENT_STATUS_SET_CROP_SCREEN_SOURCE:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input x.\n");
-               else if (g_cnt == 2)
-                       g_print("*** input y.\n");
-               else if (g_cnt == 3)
-                       g_print("*** input width.\n");
-               else if (g_cnt == 4)
-                       g_print("*** input height.\n");
-               else if (g_cnt == 5)
-                       g_print("*** input whether screen rotates (0: horizontal, 1: vertical).\n");
-               break;
-       case CURRENT_STATUS_UNSET_CROP_SCREEN_SOURCE:
-               if (g_cnt == 0)
-                       g_print("*** input source id.\n");
-               break;
-       }
-       g_print(" >>> ");
-}
-
-static void display_menu_webrtc_media_render(void)
-{
-       switch (g_menu_status) {
-       case CURRENT_STATUS_SET_DISPLAY_TYPE:
-               g_print("*** input display type.(1:overlay 2:evas)\n");
-               break;
-       case CURRENT_STATUS_SET_DISPLAY_MODE:
-               if (g_cnt == 0)
-                       g_print("*** input track id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input display mode.(1:letter-box 2:origin size 3:full)\n");
-               break;
-       case CURRENT_STATUS_GET_DISPLAY_MODE:
-               g_print("*** input track id.\n");
-               break;
-       case CURRENT_STATUS_SET_DISPLAY_VISIBLE:
-               if (g_cnt == 0)
-                       g_print("*** input track id.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input display visible.(1:true 0:false)\n");
-               break;
-       case CURRENT_STATUS_GET_DISPLAY_VISIBLE:
-               g_print("*** input track id.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_SET_AUDIO_LOOPBACK:
-               g_print("*** input source id.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK:
-               g_print("*** input source id.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_LOOPBACK:
-               g_print("*** input source id.\n");
-               break;
-       case CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK:
-               g_print("*** input source id.\n");
-               break;
-       }
-       g_print(" >>> ");
-}
-
-static void display_menu_webrtc_data_channel(void)
-{
-       switch (g_menu_status) {
-       case CURRENT_STATUS_DATA_CHANNEL_SEND_STRING:
-               g_print("*** input string to send.\n");
-               break;
-       case CURRENT_STATUS_DATA_CHANNEL_SEND_STRING_AS_BYTES:
-               g_print("*** input string to send.(it will be converted to bytes data)\n");
-               break;
-       case CURRENT_STATUS_DATA_CHANNEL_SEND_FILE:
-               g_print("*** input file path to send.\n");
-               break;
-       case CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB:
-               g_print("*** input data channel buffered amount low threshold.\n");
-               break;
-       }
-       g_print(" >>> ");
-}
-
-static void display_menu_webrtc_stats(void)
-{
-       switch (g_menu_status) {
-       case CURRENT_STATUS_FOREACH_STATS:
-               if (g_cnt == 0)
-                       g_print("*** input stats type.(1:all, 2:codec, 3:inbound-rtp/remote-outbound-rtp, 4:outbound-rtp/remote-inbound-rtp)\n");
-               break;
-       }
-       g_print(" >>> ");
-}
-
-static void display_menu_app_signaling(void)
-{
-       switch (g_menu_status) {
-       case CURRENT_STATUS_SETTING_SIGNALING_SERVER:
-               g_print("*** input signaling server URL.\n");
-               break;
-       case CURRENT_STATUS_SETTING_PROXY:
-               g_print("*** input proxy URL.\n");
-               break;
-       case CURRENT_STATUS_REQUEST_SESSION:
-               g_print("*** input remote peer id.\n");
-               break;
-       case CURRENT_STATUS_REQUEST_JOIN_ROOM:
-               if (g_cnt == 0)
-                       g_print("*** input source type.(1:audiotest/videotest 2:mic/camera 3:mic only)\n");
-               else if (g_cnt == 1)
-                       g_print("*** input room name to join.\n");
-               break;
-       case 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_PRIVATE_SIGNALING_SERVER_CREATE:
-               g_print("*** input port.\n");
-               break;
-       case CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CONNECT:
-               if (g_cnt == 0)
-                       g_print("*** input server ip.\n");
-               else if (g_cnt == 1)
-                       g_print("*** input port.\n");
-               break;
-       }
-       g_print(" >>> ");
-}
-
-static void displaymenu(void)
-{
-       if (g_menu_status == CURRENT_STATUS_MAINMENU) {
-               display_menu_main();
-
-       } else {
-               if (g_menu_status & TEST_MENU_WEBRTC_COMMON) {
-                       display_menu_webrtc_common();
-
-               } else if (g_menu_status & TEST_MENU_WEBRTC_MEDIA_SOURCE) {
-                       display_menu_webrtc_media_source();
-
-               } else if (g_menu_status & TEST_MENU_WEBRTC_MEDIA_RENDER) {
-                       display_menu_webrtc_media_render();
-
-               } else if (g_menu_status & TEST_MENU_WEBRTC_DATA_CHANNEL) {
-                       display_menu_webrtc_data_channel();
-
-               } else if (g_menu_status & TEST_MENU_WEBRTC_STATS) {
-                       display_menu_webrtc_stats();
-
-               } else if (g_menu_status & TEST_MENU_APP_SIGNALING) {
-                       display_menu_app_signaling();
-
-               } else {
-                       g_print("%s() > unknown menu status[0x%x]\n", __FUNCTION__, g_menu_status);
-                       quit_program();
-               }
-       }
-}
-
 static gboolean timeout_menu_display_cb(void *data)
 {
        displaymenu();
        return FALSE;
 }
 
-static void reset_menu_state(void)
-{
-       g_menu_status = CURRENT_STATUS_MAINMENU;
-}
-
 static void test_webrtc_common(char *cmd)
 {
        int value;
diff --git a/test/webrtc_test_menu.c b/test/webrtc_test_menu.c
new file mode 100644 (file)
index 0000000..9575eff
--- /dev/null
@@ -0,0 +1,561 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "webrtc_test_priv.h"
+
+menu_info_s g_menu_infos[] = {
+       { "none", CURRENT_STATUS_MAINMENU, false },
+       { "none", CURRENT_STATUS_TERMINATE, false },
+       { "q", CURRENT_STATUS_QUIT, false },
+       /* webrtc common */
+       { "c", CURRENT_STATUS_CREATE, false },
+       { "s", CURRENT_STATUS_START, false },
+       { "t", CURRENT_STATUS_STOP, false },
+       { "d", CURRENT_STATUS_DESTROY, false },
+       { "g", CURRENT_STATUS_GET_STATE, false },
+       { "st", CURRENT_STATUS_SET_STUN_SERVER, true },
+       { "gt", CURRENT_STATUS_GET_STUN_SERVER, false },
+       { "su", CURRENT_STATUS_ADD_TURN_SERVER, true },
+       { "gu", CURRENT_STATUS_GET_TURN_SERVERS, false },
+       { "sbp", CURRENT_STATUS_SET_BUNDLE_POLICY, true },
+       { "gbp", CURRENT_STATUS_GET_BUNDLE_POLICY, false },
+       { "stp", CURRENT_STATUS_SET_ICE_TRANSPORT_POLICY, true },
+       { "gtp", CURRENT_STATUS_GET_ICE_TRANSPORT_POLICY, false },
+       { "co", CURRENT_STATUS_CREATE_OFFER, false },
+       { "ca", CURRENT_STATUS_CREATE_ANSWER, false },
+       { "coa", CURRENT_STATUS_CREATE_OFFER_ASYNC, false },
+       { "caa", CURRENT_STATUS_CREATE_ANSWER_ASYNC, false },
+       { "sl", CURRENT_STATUS_SET_LOCAL_DESCRIPTION, true },
+       { "sr", CURRENT_STATUS_SET_REMOTE_DESCRIPTION, false },
+       { "ac", CURRENT_STATUS_ADD_ICE_CANDIDATE, false },
+       { "sac", CURRENT_STATUS_SET_ALL_CALLBACKS, false },
+       { "uac", CURRENT_STATUS_UNSET_ALL_CALLBACKS, false },
+       { "gan", CURRENT_STATUS_GET_ALL_NEGOTIATION_STATES, false },
+       { "sdp", CURRENT_STATUS_SET_RTP_PACKET_DROP_PROBABILITY, true },
+       { "gdp", CURRENT_STATUS_GET_RTP_PACKET_DROP_PROBABILITY, true },
+       /* webrtc media source */
+       { "a", CURRENT_STATUS_ADD_MEDIA_SOURCE, true },
+       { "r", CURRENT_STATUS_REMOVE_MEDIA_SOURCE, true },
+       { "td", CURRENT_STATUS_MEDIA_SOURCE_SET_TRANSCEIVER_DIRECTION, true },
+       { "gd", CURRENT_STATUS_MEDIA_SOURCE_GET_TRANSCEIVER_DIRECTION, true },
+       { "p", CURRENT_STATUS_MEDIA_SOURCE_SET_PAUSE, true },
+       { "o", CURRENT_STATUS_MEDIA_SOURCE_GET_PAUSE, true },
+       { "mu", CURRENT_STATUS_MEDIA_SOURCE_SET_MUTE, true },
+       { "mg", CURRENT_STATUS_MEDIA_SOURCE_GET_MUTE, true },
+       { "v", CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_RESOLUTION, true },
+       { "l", CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_RESOLUTION, true },
+       { "f", CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_FRAMERATE, true },
+       { "m", CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_FRAMERATE, true },
+       { "pa", CURRENT_STATUS_FILE_SOURCE_SET_PATH, true },
+       { "sfl", CURRENT_STATUS_FILE_SOURCE_SET_LOOPING, true },
+       { "gfl", CURRENT_STATUS_FILE_SOURCE_GET_LOOPING, true },
+       { "sf", CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_FORMAT, true },
+       { "sm", CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_BUFFER_STATE_CHANGED_CB, true },
+       { "um", CURRENT_STATUS_MEDIA_PACKET_SOURCE_UNSET_BUFFER_STATE_CHANGED_CB, true },
+       { "sp", CURRENT_STATUS_START_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE, true },
+       { "tp", CURRENT_STATUS_STOP_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE, true },
+       { "scs", CURRENT_STATUS_SET_CROP_SCREEN_SOURCE, true },
+       { "ucs", CURRENT_STATUS_UNSET_CROP_SCREEN_SOURCE, true },
+       /* webrtc media render */
+       { "dt", CURRENT_STATUS_SET_DISPLAY_TYPE, true },
+       { "dm", CURRENT_STATUS_SET_DISPLAY_MODE, true },
+       { "gm", CURRENT_STATUS_GET_DISPLAY_MODE, true },
+       { "dv", CURRENT_STATUS_SET_DISPLAY_VISIBLE, true },
+       { "gv", CURRENT_STATUS_GET_DISPLAY_VISIBLE, true },
+       { "sa", CURRENT_STATUS_SET_ENCODED_AUDIO_FRAME_CB, false },
+       { "ua", CURRENT_STATUS_UNSET_ENCODED_AUDIO_FRAME_CB, false },
+       { "sv", CURRENT_STATUS_SET_ENCODED_VIDEO_FRAME_CB, false },
+       { "uv", CURRENT_STATUS_UNSET_ENCODED_VIDEO_FRAME_CB, false },
+       { "al", CURRENT_STATUS_MEDIA_SOURCE_SET_AUDIO_LOOPBACK, true },
+       { "ual", CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK, true },
+       { "vl", CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_LOOPBACK, true },
+       { "uvl", CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK, true },
+       /* webrtc data channel */
+       { "cd", CURRENT_STATUS_DATA_CHANNEL_CREATE, false },
+       { "dd", CURRENT_STATUS_DATA_CHANNEL_DESTROY, false },
+       { "dl", CURRENT_STATUS_DATA_CHANNEL_GET_LABEL, false },
+       { "zs", CURRENT_STATUS_DATA_CHANNEL_SEND_STRING, true },
+       { "zb", CURRENT_STATUS_DATA_CHANNEL_SEND_STRING_AS_BYTES, true },
+       { "zf", CURRENT_STATUS_DATA_CHANNEL_SEND_FILE, true },
+       { "sbc", CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB, true },
+       { "ubc", CURRENT_STATUS_DATA_CHANNEL_UNSET_BUFFERED_AMOUNT_LOW_CB, false },
+       { "gbt", CURRENT_STATUS_DATA_CHANNEL_GET_BUFFERED_AMOUNT_LOW_THRESHOLD, false },
+       { "ba", CURRENT_STATUS_DATA_CHANNEL_GET_BUFFERED_AMOUNT, false },
+       /* webrtc stats */
+       { "sts", CURRENT_STATUS_FOREACH_STATS, true },
+       /* app. setting & signaling */
+       { "ss", CURRENT_STATUS_SETTING_SIGNALING_SERVER, true },
+       { "cs", CURRENT_STATUS_CONNECT_SIGNALING_SERVER, false },
+       { "px", CURRENT_STATUS_SETTING_PROXY, true },
+       { "rs", CURRENT_STATUS_REQUEST_SESSION, true },
+       { "rj", CURRENT_STATUS_REQUEST_JOIN_ROOM, true },
+       { "sd", CURRENT_STATUS_SEND_LOCAL_DESCRIPTION, true },
+       { "ssc", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CREATE, true },
+       { "ssd", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_DESTROY, false },
+       { "sss", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_START, false },
+       { "sst", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_STOP, false },
+       { "scc", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CONNECT, true },
+       { "scd", CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_DISCONNECT, false },
+       { NULL, -1, false },
+};
+
+void display_handle_status(int index)
+{
+       int ret = WEBRTC_ERROR_NONE;
+       webrtc_state_e state;
+       char *stun_server = NULL;
+
+       if (g_conns[index].webrtc == NULL)
+               return;
+
+       ret = webrtc_get_state(g_conns[index].webrtc, &state);
+       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+       ret = webrtc_get_stun_server(g_conns[index].webrtc, &stun_server);
+       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+       ret = webrtc_foreach_turn_server(g_conns[index].webrtc, foreach_turn_server, NULL);
+       RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret);
+
+       g_print("  webrtc[%p]", g_conns[index].webrtc);
+       g_print("  state[%s]", g_webrtc_state_str[state]);
+       if (stun_server) {
+               g_print("  STUN server[%s]", stun_server);
+               free(stun_server);
+       }
+
+       g_print("\n-----------------------------------------------------------------------------------------\n");
+}
+
+void display_setting_status(void)
+{
+       int len_proxy = strlen(g_proxy);
+       int len_server = strlen(g_signaling_server.url);
+       int i;
+
+       if (len_proxy > 0)
+               g_print("  proxy[%s]", g_proxy);
+       if (len_server > 0)
+               g_print("  server[%s][%s]\n", g_signaling_server.url, g_server_status_str[g_signaling_server.server_status]);
+       if (g_signaling_server.private_ip && g_signaling_server.port > 0)
+               g_print("  server[%s:%d][%s]\n", g_signaling_server.private_ip, g_signaling_server.port, g_server_status_str[g_signaling_server.server_status]);
+       if (g_signaling_server.local_peer_id > 0)
+               g_print("  local peer id : %d\n", g_signaling_server.local_peer_id);
+       for (i = 0; i < MAX_CONNECTION_LEN; i++) {
+               if (g_conns[i].remote_peer_id == 0)
+                       continue;
+               g_print("  [%d] remote peer id : %d\n", i, g_conns[i].remote_peer_id);
+       }
+       g_print("-----------------------------------------------------------------------------------------\n");
+}
+
+void display_menu_main(void)
+{
+       g_print("\n");
+       g_print("=========================================================================================\n");
+       g_print("                   Native WebRTC Test (press q to quit, * for internal API)\n");
+       g_print("-----------------------------------------------------------------------------------------\n");
+       display_handle_status(0);
+       g_print("c. Create\t");
+       g_print("d. Destroy\t");
+       g_print("s. Start\t");
+       g_print("t. Stop\t\t");
+       g_print("g. Get state\n");
+       g_print("sac. Set all callbacks\t");
+       g_print("uac. Unset all callbacks\n");
+       g_print("gan. Gets all the negotiation states\n");
+       g_print("st. Set STUN server\t");
+       g_print("gt. Get STUN server\t");
+       g_print("su. Add TURN server\t");
+       g_print("gu. Get TURN servers\n");
+       g_print("sbp. Set bundle policy\t");
+       g_print("gbp. Get bundle policy\n");
+       g_print("stp. Set ICE transport policy\t");
+       g_print("gtp. Get ICE transport policy\n");
+       g_print("co. Create offer\t");
+       g_print("ca. Create answer\n");
+       g_print("coa. Create offer(async)\t");
+       g_print("caa. Create answer(async)\n");
+       g_print("sl. Set local description\t");
+       g_print("sr. Set remote description\n");
+       g_print("ac. Add ICE candidate\n");
+       g_print("sdp. *Set RTP packet drop probability\t");
+       g_print("gdp. *Get RTP packet drop probability\n");
+       g_print("------------------------------------- Media Source --------------------------------------\n");
+       g_print("a. Add media source\t");
+       g_print("r. Remove media source\n");
+       g_print("p. Pause/play media source\t");
+       g_print("o. Get the media source pause\n");
+       g_print("mu. Mute/unmute media source\t");
+       g_print("mg. Get the media source mute\n");
+       g_print("v. Set video resolution\t");
+       g_print("l. Get video resolution\n");
+       g_print("f. Set video framerate\t");
+       g_print("m. Get video framerate\n");
+       g_print("td. Set transceiver direction\t");
+       g_print("gd. Get transceiver direction\n");
+       g_print("pa. Set media path to file source\n");
+       g_print("sfl. Set file source looping\t");
+       g_print("gfl. Set file source looping\n");
+       g_print("sf. Set media format to media packet source\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("scs. *Set crop screen source\t");
+       g_print("ucs. *Unset crop screen source\n");
+       g_print("------------------------------------- Media Render --------------------------------------\n");
+       g_print("dt. Set display type\t");
+       g_print("dm. Set display mode\t");
+       g_print("gm. Get display mode\n");
+       g_print("dv. Set display visible\t");
+       g_print("gv. Get display visible\n");
+       g_print("al. Set audio loopback\t");
+       g_print("ual. Unset audio loopback\n");
+       g_print("vl. Set video loopback\t");
+       g_print("uvl. Unset video loopback\n");
+       g_print("sa. Set encoded audio frame callback\t");
+       g_print("ua. Unset encoded audio frame callback\n");
+       g_print("sv. Set encoded video frame callback\t");
+       g_print("uv. Unset encoded video frame callback\n");
+       g_print("------------------------------------- Data Channel --------------------------------------\n");
+       g_print("cd. Create data channel\t");
+       g_print("dd. Destroy data channel\n");
+       g_print("dl. Get data channel label\n");
+       g_print("zs. Send string via data channel\n");
+       g_print("zb. Send string as bytes data via data channel\t");
+       g_print("zf. Send file via data channel\n");
+       g_print("ba. Get buffered amount\n");
+       g_print("sbc. Set buffered amount low callback\t");
+       g_print("ubc. Unset buffered amount low callback\n");
+       g_print("gbt. Get buffered amount low threshold\n");
+       g_print("---------------------------------------- Stats ------------------------------------------\n");
+       g_print("sts. Get stats\n");
+       g_print("------------------------------- App. Setting & Signaling --------------------------------\n");
+       display_setting_status();
+       g_print("px. Set proxy URL\n");
+       g_print("ss. Set signaling server URL\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("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");
+       g_print(" >>> ");
+}
+
+void display_menu_webrtc_common(void)
+{
+       switch (g_menu_status) {
+       case CURRENT_STATUS_SET_STUN_SERVER:
+               g_print("*** input STUN server address.\n");
+               break;
+       case CURRENT_STATUS_ADD_TURN_SERVER:
+               g_print("*** input TURN server address.\n");
+               break;
+       case CURRENT_STATUS_SET_BUNDLE_POLICY:
+               g_print("*** input bundle policy.(0:none, 1:max-bundle)\n");
+               break;
+       case CURRENT_STATUS_SET_ICE_TRANSPORT_POLICY:
+               g_print("*** input ICE transport policy.(0:all, 1:relay)\n");
+               break;
+       case CURRENT_STATUS_SET_LOCAL_DESCRIPTION:
+               g_print("*** input type of local description.(1:offer, 2:answer)\n");
+               break;
+       case CURRENT_STATUS_SET_RTP_PACKET_DROP_PROBABILITY:
+               if (g_cnt == 0)
+                       g_print("*** input side.(1:sender, 2:receiver)\n");
+               else if (g_cnt == 1)
+                       g_print("*** input drop probability.(0 ~ 1.0)\n");
+               break;
+       case CURRENT_STATUS_GET_RTP_PACKET_DROP_PROBABILITY:
+               if (g_cnt == 0)
+                       g_print("*** input side.(1:sender, 2:receiver)\n");
+               break;
+       }
+       g_print(" >>> ");
+}
+
+void display_menu_webrtc_media_source(void)
+{
+       switch (g_menu_status) {
+       case CURRENT_STATUS_ADD_MEDIA_SOURCE:
+               g_print("*** input media source type.(1:audiotest, 2:videotest, 3:mic, 4:camera, 5:screen, 6:file, 7:media packet, 8:custom audio, 9:custom video)\n");
+               break;
+       case CURRENT_STATUS_REMOVE_MEDIA_SOURCE:
+               g_print("*** input media source id to remove.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_SET_PAUSE:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input media type.(1:audio 2:video)\n");
+               else if (g_cnt == 2)
+                       g_print("*** input pause or play.(1:pause, 0:play)\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_GET_PAUSE :
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input media type.(1:audio 2:video)\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_SET_MUTE:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input media type.(1:audio 2:video)\n");
+               else if (g_cnt == 2)
+                       g_print("*** input mute mode.(1:mute 0:unmute)\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_GET_MUTE:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input media type.(1:audio 2:video)\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_RESOLUTION:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input width.\n");
+               else if (g_cnt == 2)
+                       g_print("*** input height.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_RESOLUTION:
+               g_print("*** input source id.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_FRAMERATE:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input framerate.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_FRAMERATE:
+               g_print("*** input source id.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_SET_TRANSCEIVER_DIRECTION:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input media type.(1:audio 2:video)\n");
+               else if (g_cnt == 2)
+                       g_print("*** input transceiver direction.(1:sendonly 2:recvonly 3:sendrecv)\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_GET_TRANSCEIVER_DIRECTION:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input media type.(1:audio 2:video)\n");
+               break;
+       case CURRENT_STATUS_FILE_SOURCE_SET_PATH:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input media path.\n");
+               break;
+       case CURRENT_STATUS_FILE_SOURCE_SET_LOOPING:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input looping state.(1:true 0:false)\n");
+               break;
+       case CURRENT_STATUS_FILE_SOURCE_GET_LOOPING:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_BUFFER_STATE_CHANGED_CB:
+               g_print("*** input media packet source id to set buffer state changed callback.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_PACKET_SOURCE_UNSET_BUFFER_STATE_CHANGED_CB:
+               g_print("*** input media packet source id to unset buffer state changed callback.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_FORMAT:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input media format.(1:I420 2:NV12 3:PCM_S16LE 4:H264)\n");
+               break;
+       case CURRENT_STATUS_START_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE:
+               g_print("*** input media packet source id to start pushing packet.\n");
+               break;
+       case CURRENT_STATUS_STOP_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE:
+               g_print("*** input media packet source id to stop pushing packet.\n");
+               break;
+       case CURRENT_STATUS_SET_CROP_SCREEN_SOURCE:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input x.\n");
+               else if (g_cnt == 2)
+                       g_print("*** input y.\n");
+               else if (g_cnt == 3)
+                       g_print("*** input width.\n");
+               else if (g_cnt == 4)
+                       g_print("*** input height.\n");
+               else if (g_cnt == 5)
+                       g_print("*** input whether screen rotates (0: horizontal, 1: vertical).\n");
+               break;
+       case CURRENT_STATUS_UNSET_CROP_SCREEN_SOURCE:
+               if (g_cnt == 0)
+                       g_print("*** input source id.\n");
+               break;
+       }
+       g_print(" >>> ");
+}
+
+void display_menu_webrtc_media_render(void)
+{
+       switch (g_menu_status) {
+       case CURRENT_STATUS_SET_DISPLAY_TYPE:
+               g_print("*** input display type.(1:overlay 2:evas)\n");
+               break;
+       case CURRENT_STATUS_SET_DISPLAY_MODE:
+               if (g_cnt == 0)
+                       g_print("*** input track id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input display mode.(1:letter-box 2:origin size 3:full)\n");
+               break;
+       case CURRENT_STATUS_GET_DISPLAY_MODE:
+               g_print("*** input track id.\n");
+               break;
+       case CURRENT_STATUS_SET_DISPLAY_VISIBLE:
+               if (g_cnt == 0)
+                       g_print("*** input track id.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input display visible.(1:true 0:false)\n");
+               break;
+       case CURRENT_STATUS_GET_DISPLAY_VISIBLE:
+               g_print("*** input track id.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_SET_AUDIO_LOOPBACK:
+               g_print("*** input source id.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK:
+               g_print("*** input source id.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_LOOPBACK:
+               g_print("*** input source id.\n");
+               break;
+       case CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK:
+               g_print("*** input source id.\n");
+               break;
+       }
+       g_print(" >>> ");
+}
+
+void display_menu_webrtc_data_channel(void)
+{
+       switch (g_menu_status) {
+       case CURRENT_STATUS_DATA_CHANNEL_SEND_STRING:
+               g_print("*** input string to send.\n");
+               break;
+       case CURRENT_STATUS_DATA_CHANNEL_SEND_STRING_AS_BYTES:
+               g_print("*** input string to send.(it will be converted to bytes data)\n");
+               break;
+       case CURRENT_STATUS_DATA_CHANNEL_SEND_FILE:
+               g_print("*** input file path to send.\n");
+               break;
+       case CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB:
+               g_print("*** input data channel buffered amount low threshold.\n");
+               break;
+       }
+       g_print(" >>> ");
+}
+
+void display_menu_webrtc_stats(void)
+{
+       switch (g_menu_status) {
+       case CURRENT_STATUS_FOREACH_STATS:
+               if (g_cnt == 0)
+                       g_print("*** input stats type.(1:all, 2:codec, 3:inbound-rtp/remote-outbound-rtp, 4:outbound-rtp/remote-inbound-rtp)\n");
+               break;
+       }
+       g_print(" >>> ");
+}
+
+void display_menu_app_signaling(void)
+{
+       switch (g_menu_status) {
+       case CURRENT_STATUS_SETTING_SIGNALING_SERVER:
+               g_print("*** input signaling server URL.\n");
+               break;
+       case CURRENT_STATUS_SETTING_PROXY:
+               g_print("*** input proxy URL.\n");
+               break;
+       case CURRENT_STATUS_REQUEST_SESSION:
+               g_print("*** input remote peer id.\n");
+               break;
+       case CURRENT_STATUS_REQUEST_JOIN_ROOM:
+               if (g_cnt == 0)
+                       g_print("*** input source type.(1:audiotest/videotest 2:mic/camera 3:mic only)\n");
+               else if (g_cnt == 1)
+                       g_print("*** input room name to join.\n");
+               break;
+       case 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_PRIVATE_SIGNALING_SERVER_CREATE:
+               g_print("*** input port.\n");
+               break;
+       case CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CONNECT:
+               if (g_cnt == 0)
+                       g_print("*** input server ip.\n");
+               else if (g_cnt == 1)
+                       g_print("*** input port.\n");
+               break;
+       }
+       g_print(" >>> ");
+}
+
+void displaymenu(void)
+{
+       if (g_menu_status == CURRENT_STATUS_MAINMENU) {
+               display_menu_main();
+
+       } else {
+               if (g_menu_status & TEST_MENU_WEBRTC_COMMON) {
+                       display_menu_webrtc_common();
+
+               } else if (g_menu_status & TEST_MENU_WEBRTC_MEDIA_SOURCE) {
+                       display_menu_webrtc_media_source();
+
+               } else if (g_menu_status & TEST_MENU_WEBRTC_MEDIA_RENDER) {
+                       display_menu_webrtc_media_render();
+
+               } else if (g_menu_status & TEST_MENU_WEBRTC_DATA_CHANNEL) {
+                       display_menu_webrtc_data_channel();
+
+               } else if (g_menu_status & TEST_MENU_WEBRTC_STATS) {
+                       display_menu_webrtc_stats();
+
+               } else if (g_menu_status & TEST_MENU_APP_SIGNALING) {
+                       display_menu_app_signaling();
+
+               } else {
+                       g_print("%s() > unknown menu status[0x%x]\n", __FUNCTION__, g_menu_status);
+                       quit_program();
+               }
+       }
+}
+
+void reset_menu_state(void)
+{
+       g_menu_status = CURRENT_STATUS_MAINMENU;
+}
\ No newline at end of file
diff --git a/test/webrtc_test_priv.h b/test/webrtc_test_priv.h
new file mode 100644 (file)
index 0000000..989fff2
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIA_WEBRTC_TEST_PRIVATE_H__
+#define __TIZEN_MEDIA_WEBRTC_TEST_PRIVATE_H__
+
+#include <webrtc_internal.h>
+#include <media_format.h>
+#include <media_packet_internal.h>
+#include <sound_manager.h>
+#ifndef TIZEN_TV
+#include <esplusplayer_capi.h>
+#endif
+#include <appcore-efl.h>
+#include <Elementary.h>
+#include <glib.h>
+#include <gst/gst.h>
+#include <libsoup/soup.h>
+
+//#define __DEBUG_VALIDATE_MEDIA_PACKET_SOURCE__
+//#define __DEBUG_VALIDATE_ENCODED_FRAME_CB__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RET_IF(expr, fmt, arg...) \
+do { \
+       if ((expr)) { \
+               g_printerr("failed to %s(), "fmt"\n", __func__, ##arg); \
+               return; \
+       } \
+} while (0)
+
+#define TEST_MENU_WEBRTC_COMMON         0x00001000
+#define TEST_MENU_WEBRTC_MEDIA_SOURCE   0x00002000
+#define TEST_MENU_WEBRTC_MEDIA_RENDER   0x00004000
+#define TEST_MENU_WEBRTC_DATA_CHANNEL   0x00008000
+#define TEST_MENU_WEBRTC_STATS          0x00010000
+#define TEST_MENU_APP_SIGNALING         0x00020000
+
+enum {
+       CURRENT_STATUS_MAINMENU,
+       CURRENT_STATUS_TERMINATE,
+       CURRENT_STATUS_QUIT,
+       /* webrtc common */
+       CURRENT_STATUS_CREATE = TEST_MENU_WEBRTC_COMMON | 0x01,
+       CURRENT_STATUS_START = TEST_MENU_WEBRTC_COMMON | 0x02,
+       CURRENT_STATUS_STOP = TEST_MENU_WEBRTC_COMMON | 0x03,
+       CURRENT_STATUS_DESTROY = TEST_MENU_WEBRTC_COMMON | 0x04,
+       CURRENT_STATUS_GET_STATE = TEST_MENU_WEBRTC_COMMON | 0x05,
+       CURRENT_STATUS_SET_STUN_SERVER = TEST_MENU_WEBRTC_COMMON | 0x06,
+       CURRENT_STATUS_GET_STUN_SERVER = TEST_MENU_WEBRTC_COMMON | 0x07,
+       CURRENT_STATUS_ADD_TURN_SERVER = TEST_MENU_WEBRTC_COMMON | 0x08,
+       CURRENT_STATUS_GET_TURN_SERVERS = TEST_MENU_WEBRTC_COMMON | 0x09,
+       CURRENT_STATUS_SET_BUNDLE_POLICY = TEST_MENU_WEBRTC_COMMON | 0x0A,
+       CURRENT_STATUS_GET_BUNDLE_POLICY = TEST_MENU_WEBRTC_COMMON | 0x0B,
+       CURRENT_STATUS_SET_ICE_TRANSPORT_POLICY = TEST_MENU_WEBRTC_COMMON | 0x0C,
+       CURRENT_STATUS_GET_ICE_TRANSPORT_POLICY = TEST_MENU_WEBRTC_COMMON | 0x0D,
+       CURRENT_STATUS_CREATE_OFFER = TEST_MENU_WEBRTC_COMMON | 0x0E,
+       CURRENT_STATUS_CREATE_ANSWER = TEST_MENU_WEBRTC_COMMON | 0x0F,
+       CURRENT_STATUS_CREATE_OFFER_ASYNC = TEST_MENU_WEBRTC_COMMON | 0x10,
+       CURRENT_STATUS_CREATE_ANSWER_ASYNC = TEST_MENU_WEBRTC_COMMON | 0x11,
+       CURRENT_STATUS_SET_LOCAL_DESCRIPTION = TEST_MENU_WEBRTC_COMMON | 0x12,
+       CURRENT_STATUS_SET_REMOTE_DESCRIPTION = TEST_MENU_WEBRTC_COMMON | 0x13,
+       CURRENT_STATUS_ADD_ICE_CANDIDATE = TEST_MENU_WEBRTC_COMMON | 0x14,
+       CURRENT_STATUS_SET_ALL_CALLBACKS = TEST_MENU_WEBRTC_COMMON | 0x15,
+       CURRENT_STATUS_UNSET_ALL_CALLBACKS = TEST_MENU_WEBRTC_COMMON | 0x16,
+       CURRENT_STATUS_GET_ALL_NEGOTIATION_STATES = TEST_MENU_WEBRTC_COMMON | 0x17,
+       CURRENT_STATUS_SET_RTP_PACKET_DROP_PROBABILITY = TEST_MENU_WEBRTC_COMMON | 0x18,
+       CURRENT_STATUS_GET_RTP_PACKET_DROP_PROBABILITY = TEST_MENU_WEBRTC_COMMON | 0x19,
+       /* webrtc media source */
+       CURRENT_STATUS_ADD_MEDIA_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x01,
+       CURRENT_STATUS_REMOVE_MEDIA_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x02,
+       CURRENT_STATUS_MEDIA_SOURCE_SET_TRANSCEIVER_DIRECTION = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x03,
+       CURRENT_STATUS_MEDIA_SOURCE_GET_TRANSCEIVER_DIRECTION = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x04,
+       CURRENT_STATUS_MEDIA_SOURCE_SET_PAUSE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x05,
+       CURRENT_STATUS_MEDIA_SOURCE_GET_PAUSE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x06,
+       CURRENT_STATUS_MEDIA_SOURCE_SET_MUTE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x07,
+       CURRENT_STATUS_MEDIA_SOURCE_GET_MUTE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x08,
+       CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_RESOLUTION = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x09,
+       CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_RESOLUTION = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0A,
+       CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_FRAMERATE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0B,
+       CURRENT_STATUS_MEDIA_SOURCE_GET_VIDEO_FRAMERATE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0C,
+       CURRENT_STATUS_FILE_SOURCE_SET_PATH = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0D,
+       CURRENT_STATUS_FILE_SOURCE_SET_LOOPING = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0E,
+       CURRENT_STATUS_FILE_SOURCE_GET_LOOPING = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x0F,
+       CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_FORMAT = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x10,
+       CURRENT_STATUS_MEDIA_PACKET_SOURCE_SET_BUFFER_STATE_CHANGED_CB = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x11,
+       CURRENT_STATUS_MEDIA_PACKET_SOURCE_UNSET_BUFFER_STATE_CHANGED_CB = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x12,
+       CURRENT_STATUS_START_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x13,
+       CURRENT_STATUS_STOP_PUSHING_PACKET_TO_MEDIA_PACKET_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x14,
+       CURRENT_STATUS_SET_CROP_SCREEN_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x15,
+       CURRENT_STATUS_UNSET_CROP_SCREEN_SOURCE = TEST_MENU_WEBRTC_MEDIA_SOURCE | 0x16,
+       /* webrtc media render */
+       CURRENT_STATUS_SET_DISPLAY_TYPE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x01,
+       CURRENT_STATUS_SET_DISPLAY_MODE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x02,
+       CURRENT_STATUS_GET_DISPLAY_MODE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x03,
+       CURRENT_STATUS_SET_DISPLAY_VISIBLE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x04,
+       CURRENT_STATUS_GET_DISPLAY_VISIBLE = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x05,
+       CURRENT_STATUS_SET_ENCODED_AUDIO_FRAME_CB = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x06,
+       CURRENT_STATUS_UNSET_ENCODED_AUDIO_FRAME_CB = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x07,
+       CURRENT_STATUS_SET_ENCODED_VIDEO_FRAME_CB = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x08,
+       CURRENT_STATUS_UNSET_ENCODED_VIDEO_FRAME_CB = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x09,
+       CURRENT_STATUS_MEDIA_SOURCE_SET_AUDIO_LOOPBACK = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x0A,
+       CURRENT_STATUS_MEDIA_SOURCE_UNSET_AUDIO_LOOPBACK = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x0B,
+       CURRENT_STATUS_MEDIA_SOURCE_SET_VIDEO_LOOPBACK = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x0C,
+       CURRENT_STATUS_MEDIA_SOURCE_UNSET_VIDEO_LOOPBACK = TEST_MENU_WEBRTC_MEDIA_RENDER | 0x0D,
+       /* webrtc data channel */
+       CURRENT_STATUS_DATA_CHANNEL_CREATE = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x01,
+       CURRENT_STATUS_DATA_CHANNEL_DESTROY = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x02,
+       CURRENT_STATUS_DATA_CHANNEL_GET_LABEL = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x03,
+       CURRENT_STATUS_DATA_CHANNEL_SEND_STRING = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x04,
+       CURRENT_STATUS_DATA_CHANNEL_SEND_STRING_AS_BYTES = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x05,
+       CURRENT_STATUS_DATA_CHANNEL_SEND_FILE = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x06,
+       CURRENT_STATUS_DATA_CHANNEL_SET_BUFFERED_AMOUNT_LOW_CB = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x07,
+       CURRENT_STATUS_DATA_CHANNEL_UNSET_BUFFERED_AMOUNT_LOW_CB = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x08,
+       CURRENT_STATUS_DATA_CHANNEL_GET_BUFFERED_AMOUNT_LOW_THRESHOLD = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x09,
+       CURRENT_STATUS_DATA_CHANNEL_GET_BUFFERED_AMOUNT = TEST_MENU_WEBRTC_DATA_CHANNEL | 0x0A,
+       /* webrtc stats */
+       CURRENT_STATUS_FOREACH_STATS = TEST_MENU_WEBRTC_STATS | 0x01,
+       /* app. setting & signaling */
+       CURRENT_STATUS_SETTING_SIGNALING_SERVER = TEST_MENU_APP_SIGNALING | 0x01,
+       CURRENT_STATUS_CONNECT_SIGNALING_SERVER = TEST_MENU_APP_SIGNALING | 0x02,
+       CURRENT_STATUS_SETTING_PROXY = TEST_MENU_APP_SIGNALING | 0x03,
+       CURRENT_STATUS_REQUEST_SESSION = TEST_MENU_APP_SIGNALING | 0x04,
+       CURRENT_STATUS_REQUEST_JOIN_ROOM = TEST_MENU_APP_SIGNALING | 0x05,
+       CURRENT_STATUS_SEND_LOCAL_DESCRIPTION = TEST_MENU_APP_SIGNALING | 0x06,
+       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CREATE = TEST_MENU_APP_SIGNALING | 0x07,
+       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_DESTROY = TEST_MENU_APP_SIGNALING | 0x08,
+       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_START = TEST_MENU_APP_SIGNALING | 0x09,
+       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_STOP = TEST_MENU_APP_SIGNALING | 0x0A,
+       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_CONNECT = TEST_MENU_APP_SIGNALING | 0x0B,
+       CURRENT_STATUS_PRIVATE_SIGNALING_SERVER_DISCONNECT = TEST_MENU_APP_SIGNALING | 0x0C,
+};
+
+enum {
+       SERVER_STATUS_DISCONNECTED,
+       SERVER_STATUS_CONNECTED,
+       SERVER_STATUS_SESSION_ESTABLISHED,
+       SERVER_STATUS_SESSION_CLOSED,
+       SERVER_STATUS_ROOM_ESTABLISHED,
+       SERVER_STATUS_ERROR_FOUND
+};
+
+#define MAX_STRING_LEN 512
+#define MAX_CONNECTION_LEN 3
+#define MAX_CHANNEL_LEN 10
+#define MAX_MEDIA_PACKET_SOURCE_LEN 4
+
+typedef struct {
+       GHashTable *menu_items;
+       Evas_Object *win;
+       int win_width;
+       int win_height;
+} appdata_s;
+
+typedef struct {
+       unsigned int source_id;
+       media_format_h format;
+
+       webrtc_h webrtc;
+       GstElement *src_pipeline;
+#ifdef __DEBUG_VALIDATE_MEDIA_PACKET_SOURCE__
+       GstElement *render_pipeline;
+       GstElement *appsrc;
+#endif
+       GstElement *src;
+       GstElement *sink;
+       GstElement *demux;
+       GstBus *bus;
+       guint bus_watcher;
+       gulong handoff_signal_id;
+       gulong pad_added_signal_id;
+       bool is_overflowed;
+       bool is_stop_requested;
+       GCond cond;
+       GMutex mutex;
+       bool got_eos;
+} media_packet_source_s;
+
+typedef struct _connection_s {
+       int index;
+       int remote_peer_id;
+
+       bool is_for_room;
+       bool is_offer;
+       int room_source_type;
+
+       webrtc_h webrtc;
+       webrtc_data_channel_h channels[MAX_CHANNEL_LEN];
+       int channel_index;
+       webrtc_data_channel_h recv_channels[MAX_CHANNEL_LEN];
+       char *offer;
+       char *answer;
+       char *remote_desc;
+       GList *ice_candidates;
+
+       /* receive data & dump file */
+       gint64 sum_size;
+       gchar *expected_name;
+       gint64 expected_size;
+       char* receive_buffer;
+
+       struct {
+               sound_stream_info_h stream_info;
+       } source;
+
+       struct {
+               sound_stream_info_h stream_info;
+               webrtc_display_type_e display_type;
+               Evas_Object *eo;
+               Evas_Object *text_eo;
+               unsigned int loopback_track_id;
+#ifndef TIZEN_TV
+               esplusplayer_handle espp;
+#endif
+       } render;
+
+#ifndef TIZEN_TV
+       bool encoded_video_frame_cb_is_set;
+       bool encoded_audio_frame_cb_is_set;
+#endif
+#ifdef __DEBUG_VALIDATE_ENCODED_FRAME_CB__
+       GstElement *audio_render_pipeline;
+       GstElement *video_render_pipeline;
+       GstElement *appsrc_for_audio;
+       GstElement *appsrc_for_video;
+#endif
+       media_packet_source_s packet_sources[MAX_MEDIA_PACKET_SOURCE_LEN];
+} connection_s;
+
+typedef struct _signaling_server_s {
+       gchar url[MAX_STRING_LEN];
+       SoupWebsocketConnection *ws_conn;
+       int server_status;
+       gint32 local_peer_id;
+
+       /* for private network - internal API */
+       webrtc_signaling_client_h signaling_client;
+       char *private_ip;
+       int port;
+       bool is_connected;
+} signaling_server_s;
+
+typedef struct {
+       const char *cmd;
+       int status;
+       bool key_input_needed;
+} menu_info_s;
+
+extern menu_info_s g_menu_infos[];
+extern const char *g_server_status_str[];
+extern const char *g_webrtc_state_str[];
+extern int g_menu_status;
+extern int g_cnt;
+extern gchar g_proxy[];
+extern appdata_s g_ad;
+extern connection_s g_conns[];
+extern signaling_server_s g_signaling_server;
+
+void display_handle_status(int index);
+void display_setting_status(void);
+void display_menu_main(void);
+void display_menu_webrtc_common(void);
+void display_menu_webrtc_media_source(void);
+void display_menu_webrtc_media_render(void);
+void display_menu_webrtc_data_channel(void);
+void display_menu_webrtc_stats(void);
+void display_menu_app_signaling(void);
+void displaymenu(void);
+void reset_menu_state(void);
+void quit_program(void);
+bool foreach_turn_server(const char *turn_server, gpointer user_data);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file