Ticket #594: Improvements in PocketPJ Windows Mobile application: added TCP option, VAD option, option to select codec priority order, and auto-answer option

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2211 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip-apps/src/pocketpj/PocketPJ.rc b/pjsip-apps/src/pocketpj/PocketPJ.rc
index 4e55172..f5488fd 100644
--- a/pjsip-apps/src/pocketpj/PocketPJ.rc
+++ b/pjsip-apps/src/pocketpj/PocketPJ.rc
@@ -79,7 +79,7 @@
 // Dialog

 //

 

-IDD_POCKETPJ_DIALOG DIALOG DISCARDABLE  0, 0, 139, 151

+IDD_POCKETPJ_DIALOG DIALOGEX 0, 0, 139, 151

 STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION

 EXSTYLE WS_EX_APPWINDOW | 0x80000000L

 CAPTION "PocketPJ"

@@ -87,7 +87,7 @@
 BEGIN

     LTEXT           "sip:user@pjsip.lab",IDC_ACC_ID,22,5,115,8

     CONTROL         135,IDC_BTN_ACC,"Static",SS_BITMAP | SS_NOTIFY | 

-                    WS_TABSTOP,7,3,12,11

+                    WS_BORDER | WS_TABSTOP,7,3,12,11

     CONTROL         "List1",IDC_BUDDY_LIST,"SysListView32",LVS_SMALLICON | 

                     LVS_SINGLESEL | LVS_SORTASCENDING | WS_BORDER | 

                     WS_TABSTOP,7,35,127,109

@@ -97,33 +97,43 @@
                     WS_BORDER,125,16,12,11

 END

 

-IDD_SETTING DIALOG DISCARDABLE  0, 0, 140, 127

+IDD_SETTING DIALOG DISCARDABLE  0, 0, 140, 143

 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

 CAPTION "PocketPJ Settings.."

 FONT 8, "System"

 BEGIN

-    LTEXT           "Domain:",IDC_STATIC,7,8,30,9

     EDITTEXT        IDC_DOMAIN,38,7,78,12,ES_AUTOHSCROLL

     EDITTEXT        IDC_USER,38,21,78,12,ES_AUTOHSCROLL

     EDITTEXT        IDC_PASSWD,38,35,78,12,ES_PASSWORD | ES_AUTOHSCROLL

+    EDITTEXT        IDC_DNS,38,49,78,12,ES_AUTOHSCROLL

+    EDITTEXT        IDC_STUN_SRV,56,64,77,12,ES_AUTOHSCROLL

+    CONTROL         "ICE",IDC_ICE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,79,

+                    24,10

+    CONTROL         "TCP",IDC_TCP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,33,

+                    79,24,10

+    CONTROL         "SRTP",IDC_SRTP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,61,

+                    79,29,10

+    CONTROL         "PUBLISH",IDC_PUBLISH,"Button",BS_AUTOCHECKBOX | 

+                    WS_TABSTOP,93,79,40,10

+    CONTROL         "EC, tail:",IDC_ECHO_SUPPRESS,"Button",BS_AUTOCHECKBOX | 

+                    WS_TABSTOP,7,92,37,10

+    EDITTEXT        IDC_EC_TAIL,47,91,23,12,ES_AUTOHSCROLL

+    CONTROL         "VAD",IDC_VAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,

+                    92,25,10

+    COMBOBOX        IDC_CODECS,59,105,42,39,CBS_DROPDOWNLIST | WS_VSCROLL | 

+                    WS_TABSTOP

+    PUSHBUTTON      "OK",IDOK,17,122,50,14

+    PUSHBUTTON      "Cancel",IDCANCEL,73,122,50,14

+    LTEXT           "Domain:",IDC_STATIC,7,8,30,9

     LTEXT           "User:",IDC_STATIC,7,22,30,9

     LTEXT           "Passwd:",IDC_STATIC,7,36,30,9

     CONTROL         "STUN Srv:",IDC_STUN,"Button",BS_AUTOCHECKBOX | 

                     WS_TABSTOP,7,65,47,10

-    EDITTEXT        IDC_STUN_SRV,56,64,77,12,ES_AUTOHSCROLL

-    CONTROL         "ICE",IDC_ICE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,79,

-                    27,10

-    CONTROL         "SRTP",IDC_SRTP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,47,

-                    79,33,10

-    CONTROL         "PUBLISH",IDC_PUBLISH,"Button",BS_AUTOCHECKBOX | 

-                    WS_TABSTOP,85,79,43,10

-    EDITTEXT        IDC_DNS,38,49,78,12,ES_AUTOHSCROLL

     LTEXT           "DNS:",IDC_STATIC,8,50,30,9

-    PUSHBUTTON      "OK",IDOK,17,106,50,14

-    PUSHBUTTON      "Cancel",IDCANCEL,73,106,50,14

-    CONTROL         "Suppress echo, tail:",IDC_ECHO_SUPPRESS,"Button",

-                    BS_AUTOCHECKBOX | WS_TABSTOP,7,92,79,10

-    EDITTEXT        IDC_EC_TAIL,89,91,33,12,ES_AUTOHSCROLL

+    LTEXT           "ms",IDC_STATIC,75,92,13,9

+    LTEXT           "Codec priority:",IDC_STATIC,7,107,49,9

+    CONTROL         "AA",IDC_AA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,107,

+                    107,25,10

 END

 

 

@@ -192,7 +202,7 @@
         LEFTMARGIN, 7

         RIGHTMARGIN, 133

         TOPMARGIN, 7

-        BOTTOMMARGIN, 120

+        BOTTOMMARGIN, 136

     END

 END

 #endif    // APSTUDIO_INVOKED

diff --git a/pjsip-apps/src/pocketpj/PocketPJ.vcc b/pjsip-apps/src/pocketpj/PocketPJ.vcc
index 80c3c6f..5320b2d 100644
--- a/pjsip-apps/src/pocketpj/PocketPJ.vcc
+++ b/pjsip-apps/src/pocketpj/PocketPJ.vcc
@@ -12,9 +12,9 @@
 Class2=CPocketPJDlg

 

 ResourceCount=5

-Resource2=IDD_SETTING

+Resource2=IDR_ACC_MENU

 Resource3=IDD_POCKETPJ_DIALOG

-Resource4=IDR_ACC_MENU

+Resource4=IDD_SETTING

 Resource1=IDR_MAINFRAME

 Class3=CSettingsDlg

 Resource5=IDR_URI_MENU

@@ -40,7 +40,7 @@
 Class=CPocketPJDlg

 ControlCount=6

 Control1=IDC_ACC_ID,static,1342308352

-Control2=IDC_BTN_ACC,static,1342243086

+Control2=IDC_BTN_ACC,static,1350631694

 Control3=IDC_BUDDY_LIST,SysListView32,1350631446

 Control4=IDC_STATIC,static,1342308352

 Control5=IDC_URL,edit,1350631552

@@ -66,24 +66,30 @@
 [DLG:IDD_SETTING]

 Type=1

 Class=CSettingsDlg

-ControlCount=17

-Control1=IDC_STATIC,static,1342308352

-Control2=IDC_DOMAIN,edit,1350631552

-Control3=IDC_USER,edit,1350631552

-Control4=IDC_PASSWD,edit,1350631584

-Control5=IDC_STATIC,static,1342308352

-Control6=IDC_STATIC,static,1342308352

-Control7=IDC_STUN,button,1342242819

-Control8=IDC_STUN_SRV,edit,1350631552

-Control9=IDC_ICE,button,1342242819

-Control10=IDC_SRTP,button,1342242819

-Control11=IDC_PUBLISH,button,1342242819

-Control12=IDC_DNS,edit,1350631552

-Control13=IDC_STATIC,static,1342308352

+ControlCount=23

+Control1=IDC_DOMAIN,edit,1350631552

+Control2=IDC_USER,edit,1350631552

+Control3=IDC_PASSWD,edit,1350631584

+Control4=IDC_DNS,edit,1350631552

+Control5=IDC_STUN_SRV,edit,1350631552

+Control6=IDC_ICE,button,1342242819

+Control7=IDC_TCP,button,1342242819

+Control8=IDC_SRTP,button,1342242819

+Control9=IDC_PUBLISH,button,1342242819

+Control10=IDC_ECHO_SUPPRESS,button,1342242819

+Control11=IDC_EC_TAIL,edit,1350631552

+Control12=IDC_VAD,button,1342242819

+Control13=IDC_CODECS,combobox,1344339971

 Control14=IDOK,button,1342242816

 Control15=IDCANCEL,button,1342242816

-Control16=IDC_ECHO_SUPPRESS,button,1342242819

-Control17=IDC_EC_TAIL,edit,1350631552

+Control16=IDC_STATIC,static,1342308352

+Control17=IDC_STATIC,static,1342308352

+Control18=IDC_STATIC,static,1342308352

+Control19=IDC_STUN,button,1342242819

+Control20=IDC_STATIC,static,1342308352

+Control21=IDC_STATIC,static,1342308352

+Control22=IDC_STATIC,static,1342308352

+Control23=IDC_AA,button,1342242819

 

 [CLS:CSettingsDlg]

 Type=0

@@ -92,5 +98,5 @@
 BaseClass=CDialog

 Filter=D

 VirtualFilter=dWC

-LastObject=IDC_ECHO_SUPPRESS

+LastObject=CSettingsDlg

 

diff --git a/pjsip-apps/src/pocketpj/PocketPJDlg.cpp b/pjsip-apps/src/pocketpj/PocketPJDlg.cpp
index b6b7e3f..4f388b4 100644
--- a/pjsip-apps/src/pocketpj/PocketPJDlg.cpp
+++ b/pjsip-apps/src/pocketpj/PocketPJDlg.cpp
@@ -80,6 +80,7 @@
 
 BOOL CPocketPJDlg::Restart()
 {
+    unsigned i;
     pj_status_t status;
 
     char ver[80];
@@ -178,6 +179,7 @@
     media_cfg.quality = 5;
     media_cfg.thread_cnt = 1;
     media_cfg.enable_ice = m_Cfg.m_UseIce;
+    media_cfg.no_vad = !m_Cfg.m_VAD;
 
     if (m_Cfg.m_EchoSuppress) {
 	media_cfg.ec_options = PJMEDIA_ECHO_SIMPLE;
@@ -195,7 +197,7 @@
     }
 
     // Create one UDP transport
-    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Add transport..");
+    PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding UDP transport..");
     pjsua_transport_id transport_id;
     pjsua_transport_config udp_cfg;
 
@@ -210,16 +212,35 @@
 	return FALSE;
     }
 
+    if (m_Cfg.m_TCP) {
+	// Create one TCP transport
+	PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Adding TCP transport..");
+	pjsua_transport_id transport_id;
+	pjsua_transport_config tcp_cfg;
+
+	pjsua_transport_config_default(&tcp_cfg);
+	tcp_cfg.port = 0;
+	status = pjsua_transport_create(PJSIP_TRANSPORT_TCP,
+					&tcp_cfg, &transport_id);
+	if (status != PJ_SUCCESS) {
+	    Error(_T("Error creating TCP transport"), status);
+	    pjsua_destroy();
+	    PopUp_Hide(POPUP_REGISTRATION);
+	    return FALSE;
+	}
+    }
+
     // Adjust codecs priority
     pj_str_t tmp;
-    pjsua_codec_set_priority(pj_cstr(&tmp, "speex"), 0);
-    pjsua_codec_set_priority(pj_cstr(&tmp, "speex/8000"), 200);
-    pjsua_codec_set_priority(pj_cstr(&tmp, "GSM"),  180);
-    pjsua_codec_set_priority(pj_cstr(&tmp, "PCMU"), 160);
-    pjsua_codec_set_priority(pj_cstr(&tmp, "PCMA"), 150);
-    pjsua_codec_set_priority(pj_cstr(&tmp, "iLBC"), 0);
-    pjsua_codec_set_priority(pj_cstr(&tmp, "L16"), 0);
+    pjsua_codec_set_priority(pj_cstr(&tmp, "*"), 0);
+    for (i=0; i<(unsigned)m_Cfg.m_Codecs.GetSize(); ++i) {
+	CString codec = m_Cfg.m_Codecs.GetAt(i);
+	char tmp_nam[80];
 
+	pj_unicode_to_ansi((LPCTSTR)codec, codec.GetLength(),
+			   tmp_nam, sizeof(tmp_nam));
+	pjsua_codec_set_priority(pj_cstr(&tmp, tmp_nam), 200-i);
+    }
 
     // Start!
     PopUp_Modify(POPUP_REGISTRATION, POPUP_EL_TITLE3, "Starting..");
@@ -261,6 +282,15 @@
     acc_cfg.srtp_secure_signaling = 0;
     acc_cfg.publish_enabled = m_Cfg.m_UsePublish;
     
+    char route[80];
+    if (m_Cfg.m_TCP) {
+	snprintf(route, sizeof(route), "<sip:%s;lr;transport=tcp>", domain);
+	acc_cfg.proxy[acc_cfg.proxy_cnt++] = pj_str(route);
+    } else {
+	snprintf(route, sizeof(route), "<sip:%s;lr>", domain);
+	acc_cfg.proxy[acc_cfg.proxy_cnt++] = pj_str(route);
+    }
+
     status = pjsua_acc_add(&acc_cfg, PJ_TRUE, &m_PjsuaAccId);
     if (status != PJ_SUCCESS) {
 	Error(_T("Invalid account settings"), status);
@@ -366,6 +396,8 @@
 	PopUp_Show(POPUP_CALL, "Incoming call..", ci.remote_info.ptr, "",
 		   "Answer", "Hangup", 0);
 	pjsua_call_answer(0, 180, NULL, NULL);
+	if (m_Cfg.m_AutoAnswer)
+	    OnPopUpButton(1);
 	break;
     case PJSIP_INV_STATE_EARLY:	    /**< After response with To tag.	    */
     case PJSIP_INV_STATE_CONNECTING:/**< After 2xx is sent/received.	    */
diff --git a/pjsip-apps/src/pocketpj/SettingsDlg.cpp b/pjsip-apps/src/pocketpj/SettingsDlg.cpp
index af49a1e..1357044 100644
--- a/pjsip-apps/src/pocketpj/SettingsDlg.cpp
+++ b/pjsip-apps/src/pocketpj/SettingsDlg.cpp
@@ -4,6 +4,7 @@
 #include "stdafx.h"
 #include "PocketPJ.h"
 #include "SettingsDlg.h"
+#include <pjsua-lib/pjsua.h>
 #include <atlbase.h>
 
 #ifdef _DEBUG
@@ -26,14 +27,31 @@
 #define REG_BUDDY_X	_T("Buddy%u")
 #define REG_ENABLE_EC	_T("EnableEC")
 #define REG_EC_TAIL	_T("ECTail")
+#define REG_ENABLE_VAD	_T("EnableVAD")
+#define REG_ENABLE_TCP	_T("EnableTCP")
+#define REG_CODEC_CNT	_T("CodecCnt")
+#define REG_CODEC_X	_T("Codec%u")
+#define REG_AUTO_ANSWER	_T("AutoAnswer")
 
 
 /////////////////////////////////////////////////////////////////////////////
 // Settings
 CPocketPJSettings::CPocketPJSettings()
 : m_UseStun(FALSE), m_UseIce(FALSE), m_UseSrtp(FALSE), m_UsePublish(FALSE),
-  m_EchoSuppress(TRUE), m_EcTail(200)
+  m_EchoSuppress(TRUE), m_EcTail(200), m_TCP(FALSE), m_VAD(FALSE),
+  m_AutoAnswer(FALSE)
 {
+    /* Init codec list */
+#if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC
+    m_Codecs.Add(_T("GSM"));
+#endif
+#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC
+    m_Codecs.Add(_T("PCMU"));
+    m_Codecs.Add(_T("PCMA"));
+#endif
+#if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC
+    m_Codecs.Add(_T("Speex"));
+#endif
 }
 
 // Load from registry
@@ -76,21 +94,15 @@
     dwordVal = 0;
     if (key.QueryValue(dwordVal, REG_USE_STUN) == ERROR_SUCCESS) {
 	m_UseStun = dwordVal != 0;
-    } else {
-	m_UseStun = 0;
     }
 
     if (key.QueryValue(dwordVal, REG_USE_ICE) == ERROR_SUCCESS) {
 	m_UseIce = dwordVal != 0;
-    } else {
-	m_UseIce = 0;
     }
 
 
     if (key.QueryValue(dwordVal, REG_USE_SRTP) == ERROR_SUCCESS) {
 	m_UseSrtp = dwordVal != 0;
-    } else {
-	m_UseSrtp = 0;
     }
 
 
@@ -102,15 +114,26 @@
     cbData = sizeof(dwordVal);
     if (key.QueryValue(dwordVal, REG_ENABLE_EC) == ERROR_SUCCESS) {
 	m_EchoSuppress = dwordVal != 0;
-    } else {
-	m_EchoSuppress = 1;
     }
 
     cbData = sizeof(dwordVal);
     if (key.QueryValue(dwordVal, REG_EC_TAIL) == ERROR_SUCCESS) {
 	m_EcTail = dwordVal;
-    } else {
-	m_EcTail = 200;
+    }
+
+    cbData = sizeof(dwordVal);
+    if (key.QueryValue(dwordVal, REG_ENABLE_TCP) == ERROR_SUCCESS) {
+	m_TCP = dwordVal != 0;
+    }
+
+    cbData = sizeof(dwordVal);
+    if (key.QueryValue(dwordVal, REG_ENABLE_VAD) == ERROR_SUCCESS) {
+	m_VAD = dwordVal != 0;
+    }
+
+    cbData = sizeof(dwordVal);
+    if (key.QueryValue(dwordVal, REG_AUTO_ANSWER) == ERROR_SUCCESS) {
+	m_AutoAnswer = dwordVal != 0;
     }
 
     m_BuddyList.RemoveAll();
@@ -132,6 +155,23 @@
 	}
     }
 
+    DWORD codecCount = 0;
+    cbData = sizeof(dwordVal);
+    if (key.QueryValue(codecCount, REG_CODEC_CNT) == ERROR_SUCCESS) {
+
+	m_Codecs.RemoveAll();
+
+	for (i=0; i<codecCount; ++i) {
+	    CString entry;
+	    entry.Format(REG_CODEC_X, i);
+
+	    cbData = sizeof(textVal);
+	    if (key.QueryValue(textVal, entry, &cbData) == ERROR_SUCCESS) {
+		m_Codecs.Add(textVal);
+	    }
+	}
+    }
+
     key.Close();
 }
 
@@ -157,6 +197,10 @@
     key.SetValue(m_EchoSuppress, REG_ENABLE_EC);
     key.SetValue(m_EcTail, REG_EC_TAIL);
 
+    key.SetValue(m_TCP, REG_ENABLE_TCP);
+    key.SetValue(m_VAD, REG_ENABLE_VAD);
+    key.SetValue(m_AutoAnswer, REG_AUTO_ANSWER);
+
     key.SetValue(m_BuddyList.GetSize(), REG_BUDDY_CNT);
 
     int i;
@@ -166,6 +210,14 @@
 	key.SetValue(m_BuddyList.GetAt(i), entry);
     }
 
+    DWORD N = m_Codecs.GetSize();
+    key.SetValue(N, REG_CODEC_CNT);
+    for (i=0; i<m_Codecs.GetSize(); ++i) {
+	CString entry;
+	entry.Format(REG_CODEC_X, i);
+	key.SetValue(m_Codecs.GetAt(i), entry);
+    }
+
     key.Close();
 }
 
@@ -189,6 +241,9 @@
 	m_Dns = _T("");
 	m_EchoSuppress = FALSE;
 	m_EcTail = _T("");
+	m_TCP = FALSE;
+	m_VAD = FALSE;
+	m_AutoAnswer = FALSE;
 	//}}AFX_DATA_INIT
 
 	m_Domain    = m_Cfg.m_Domain;
@@ -201,10 +256,14 @@
 	m_User	    = m_Cfg.m_User;
 	m_Dns	    = m_Cfg.m_DNS;
 	m_EchoSuppress = m_Cfg.m_EchoSuppress;
+	m_TCP	    = m_Cfg.m_TCP;
+	m_VAD	    = m_Cfg.m_VAD;
+	m_AutoAnswer= m_Cfg.m_AutoAnswer;
 
 	CString s;
 	s.Format(_T("%d"), m_Cfg.m_EcTail);
 	m_EcTail    = s;
+
 }
 
 
@@ -212,6 +271,7 @@
 {
 	CDialog::DoDataExchange(pDX);
 	//{{AFX_DATA_MAP(CSettingsDlg)
+	DDX_Control(pDX, IDC_CODECS, m_Codecs);
 	DDX_Text(pDX, IDC_DOMAIN, m_Domain);
 	DDX_Check(pDX, IDC_ICE, m_ICE);
 	DDX_Text(pDX, IDC_PASSWD, m_Passwd);
@@ -223,7 +283,19 @@
 	DDX_Text(pDX, IDC_DNS, m_Dns);
 	DDX_Check(pDX, IDC_ECHO_SUPPRESS, m_EchoSuppress);
 	DDX_Text(pDX, IDC_EC_TAIL, m_EcTail);
+	DDX_Check(pDX, IDC_TCP, m_TCP);
+	DDX_Check(pDX, IDC_VAD, m_VAD);
+	DDX_Check(pDX, IDC_AA, m_AutoAnswer);
 	//}}AFX_DATA_MAP
+
+	
+	if (m_Codecs.GetCount() == 0) {
+	    int i;
+	    for (i=0; i<m_Cfg.m_Codecs.GetSize(); ++i) {
+		m_Codecs.AddString(m_Cfg.m_Codecs.GetAt(i));
+	    }
+	    m_Codecs.SetCurSel(0);
+	}
 }
 
 
@@ -231,6 +303,7 @@
 	//{{AFX_MSG_MAP(CSettingsDlg)
 	ON_BN_CLICKED(IDC_STUN, OnStun)
 	ON_BN_CLICKED(IDC_ECHO_SUPPRESS, OnEchoSuppress)
+	ON_CBN_SELCHANGE(IDC_CODECS, OnSelchangeCodecs)
 	//}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
@@ -241,20 +314,6 @@
 {
     int rc = CDialog::DoModal();	
 
-    if (rc == IDOK) {
-	m_Cfg.m_Domain	    = m_Domain;
-	m_Cfg.m_UseIce	    = m_ICE != 0;
-	m_Cfg.m_Password    = m_Passwd;
-	m_Cfg.m_UsePublish  = m_PUBLISH != 0;
-	m_Cfg.m_UseSrtp	    = m_SRTP != 0;
-	m_Cfg.m_UseStun	    = m_STUN != 0;
-	m_Cfg.m_StunSrv	    = m_StunSrv;
-	m_Cfg.m_User	    = m_User;
-	m_Cfg.m_DNS	    = m_Dns;
-	m_Cfg.m_EchoSuppress= m_EchoSuppress != 0;
-	m_Cfg.m_EcTail	    = _ttoi(m_EcTail);
-    }
-
     return rc;
 }
 
@@ -265,3 +324,53 @@
 void CSettingsDlg::OnEchoSuppress() 
 {
 }
+
+void CSettingsDlg::OnSelchangeCodecs() 
+{
+    int cur = m_Codecs.GetCurSel();
+    if (cur < 1)
+	return;
+
+    CString codec;
+    DWORD N;
+
+    m_Codecs.GetLBText(cur, codec);
+    N = m_Codecs.GetCount();
+    m_Codecs.DeleteString(cur);
+    N = m_Codecs.GetCount();
+    m_Codecs.InsertString(0, codec);
+    N = m_Codecs.GetCount();
+    m_Codecs.SetCurSel(0);
+}
+
+
+void CSettingsDlg::OnOK() 
+{
+    UpdateData(TRUE);
+
+    m_Cfg.m_Domain	= m_Domain;
+    m_Cfg.m_UseIce	= m_ICE != 0;
+    m_Cfg.m_Password	= m_Passwd;
+    m_Cfg.m_UsePublish	= m_PUBLISH != 0;
+    m_Cfg.m_UseSrtp	= m_SRTP != 0;
+    m_Cfg.m_UseStun	= m_STUN != 0;
+    m_Cfg.m_StunSrv	= m_StunSrv;
+    m_Cfg.m_User	= m_User;
+    m_Cfg.m_DNS		= m_Dns;
+    m_Cfg.m_EchoSuppress= m_EchoSuppress != 0;
+    m_Cfg.m_EcTail	= _ttoi(m_EcTail);
+    m_Cfg.m_TCP		= m_TCP != 0;
+    m_Cfg.m_VAD		= m_VAD != 0;
+    m_Cfg.m_AutoAnswer	= m_AutoAnswer != 0;
+
+    unsigned i;
+    m_Cfg.m_Codecs.RemoveAll();
+    DWORD N = m_Codecs.GetCount();
+    for (i=0; i<N; ++i) {
+	CString codec;
+	m_Codecs.GetLBText(i, codec);
+	m_Cfg.m_Codecs.Add(codec);
+    }
+
+    CDialog::OnOK();
+}
diff --git a/pjsip-apps/src/pocketpj/SettingsDlg.h b/pjsip-apps/src/pocketpj/SettingsDlg.h
index 95ec317..816ede9 100644
--- a/pjsip-apps/src/pocketpj/SettingsDlg.h
+++ b/pjsip-apps/src/pocketpj/SettingsDlg.h
@@ -23,7 +23,11 @@
     CString	m_DNS;
     bool	m_EchoSuppress;
     DWORD	m_EcTail;
+    bool	m_TCP;
+    bool	m_VAD;
+    bool	m_AutoAnswer;
 
+    CArray<CString,CString> m_Codecs;
     CArray<CString,CString> m_BuddyList;
     
     CPocketPJSettings();
@@ -48,6 +52,7 @@
 // Dialog Data
 	//{{AFX_DATA(CSettingsDlg)
 	enum { IDD = IDD_SETTING };
+	CComboBox	m_Codecs;
 	CString	m_Domain;
 	BOOL	m_ICE;
 	CString	m_Passwd;
@@ -59,6 +64,9 @@
 	CString	m_Dns;
 	BOOL	m_EchoSuppress;
 	CString	m_EcTail;
+	BOOL	m_TCP;
+	BOOL	m_VAD;
+	BOOL	m_AutoAnswer;
 	//}}AFX_DATA
 
 
@@ -79,6 +87,8 @@
 	//{{AFX_MSG(CSettingsDlg)
 	afx_msg void OnStun();
 	afx_msg void OnEchoSuppress();
+	afx_msg void OnSelchangeCodecs();
+	virtual void OnOK();
 	//}}AFX_MSG
 	DECLARE_MESSAGE_MAP()
 };
diff --git a/pjsip-apps/src/pocketpj/resource.h b/pjsip-apps/src/pocketpj/resource.h
index 1ba70d3..85eefa2 100644
--- a/pjsip-apps/src/pocketpj/resource.h
+++ b/pjsip-apps/src/pocketpj/resource.h
@@ -37,6 +37,10 @@
 #define IDC_BUTTON1                     1021
 #define IDC_EC_TAIL                     1021
 #define IDC_BUTTON2                     1022
+#define IDC_VAD                         1022
+#define IDC_TCP                         1023
+#define IDC_CODECS                      1024
+#define IDC_AA                          1025
 #define IDS_CAP_ONLINE                  32772
 #define IDS_CAP_OFFLINE                 32774
 #define IDS_CAP_INVISIBLE               32776
@@ -61,7 +65,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        145
 #define _APS_NEXT_COMMAND_VALUE         32796
-#define _APS_NEXT_CONTROL_VALUE         1023
+#define _APS_NEXT_CONTROL_VALUE         1025
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif