Index: /pjproject/trunk/build.symbian/pjmedia.mmp
===================================================================
--- /pjproject/trunk/build.symbian/pjmedia.mmp	(revision 1247)
+++ /pjproject/trunk/build.symbian/pjmedia.mmp	(revision 1248)
@@ -47,4 +47,5 @@
 SOURCE		splitcomb.c
 SOURCE		stream.c
+SOURCE		tonegen.c
 SOURCE		transport_ice.c
 SOURCE		transport_udp.c
Index: /pjproject/trunk/build.symbian/pjproject.cww
===================================================================
--- /pjproject/trunk/build.symbian/pjproject.cww	(revision 1247)
+++ /pjproject/trunk/build.symbian/pjproject.cww	(revision 1248)
@@ -272,6 +272,6 @@
         </FRAMELOC>
         <FRAMESIZE>
-            <W>605</W>
-            <H>778</H>
+            <W>629</W>
+            <H>859</H>
         </FRAMESIZE>
         <DOCKINFO>
@@ -297,6 +297,6 @@
         </FRAMELOC>
         <FRAMESIZE>
-            <W>470</W>
-            <H>705</H>
+            <W>534</W>
+            <H>921</H>
         </FRAMESIZE>
         <DOCKINFO>
@@ -322,6 +322,6 @@
         </FRAMELOC>
         <FRAMESIZE>
-            <W>904</W>
-            <H>1791</H>
+            <W>1008</W>
+            <H>2142</H>
         </FRAMESIZE>
         <DOCKINFO>
@@ -341,5 +341,4 @@
         <SESSION>-2147483648</SESSION>
         <EDOCTYPE>23</EDOCTYPE>
-        <MAXIMIZED>true</MAXIMIZED>
         <FRAMELOC>
             <X>6</X>
Index: /pjproject/trunk/pjlib/src/pj/ioqueue_symbian.cpp
===================================================================
--- /pjproject/trunk/pjlib/src/pj/ioqueue_symbian.cpp	(revision 1247)
+++ /pjproject/trunk/pjlib/src/pj/ioqueue_symbian.cpp	(revision 1248)
@@ -649,4 +649,8 @@
 				     pj_uint32_t flags )
 {
+    // If socket has reader, delete it.
+    if (key->cbObj->get_pj_socket()->Reader())
+    	key->cbObj->get_pj_socket()->DestroyReader();
+    
     // Clear flag
     flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;
@@ -668,4 +672,8 @@
 					 int *addrlen)
 {
+    // If socket has reader, delete it.
+    if (key->cbObj->get_pj_socket()->Reader())
+    	key->cbObj->get_pj_socket()->DestroyReader();
+    
     if (key->cbObj->IsActive())
 	return PJ_EBUSY;
Index: /pjproject/trunk/pjlib/src/pj/os_core_symbian.cpp
===================================================================
--- /pjproject/trunk/pjlib/src/pj/os_core_symbian.cpp	(revision 1247)
+++ /pjproject/trunk/pjlib/src/pj/os_core_symbian.cpp	(revision 1248)
@@ -422,4 +422,9 @@
 {
     User::After(msec*1000);
+    
+    TInt aError;
+    while (CActiveScheduler::RunIfReady(aError, EPriorityMuchLess))
+    	;
+    
     return PJ_SUCCESS;
 }
Index: /pjproject/trunk/pjlib/src/pj/os_symbian.h
===================================================================
--- /pjproject/trunk/pjlib/src/pj/os_symbian.h	(revision 1247)
+++ /pjproject/trunk/pjlib/src/pj/os_symbian.h	(revision 1248)
@@ -87,4 +87,7 @@
     CPjSocketReader *CreateReader(unsigned max_len=CPjSocket::MAX_LEN);
 
+    // Delete socket reader when it's not wanted.
+    void DestroyReader();
+    
 private:
     RSocket	     sock_;	    // Must not be reference, or otherwise
@@ -188,9 +191,4 @@
 public:
     //
-    // Construct PjSymbianOS instance.
-    //
-    static PjSymbianOS *NewL();
-
-    //
     // Get the singleton instance of PjSymbianOS
     //
Index: /pjproject/trunk/pjlib/src/pj/sock_symbian.cpp
===================================================================
--- /pjproject/trunk/pjlib/src/pj/sock_symbian.cpp	(revision 1247)
+++ /pjproject/trunk/pjlib/src/pj/sock_symbian.cpp	(revision 1248)
@@ -67,4 +67,19 @@
 CPjSocket::~CPjSocket()
 {
+    DestroyReader();
+    sock_.Close();
+}
+
+
+// Create socket reader.
+CPjSocketReader *CPjSocket::CreateReader(unsigned max_len)
+{
+    pj_assert(sockReader_ == NULL);
+    return sockReader_ = CPjSocketReader::NewL(*this, max_len);
+}
+
+// Delete socket reader when it's not wanted.
+void CPjSocket::DestroyReader() 
+{
     if (sockReader_) {
 	if (sockReader_->IsActive())
@@ -73,13 +88,4 @@
 	sockReader_ = NULL;
     }
-    sock_.Close();
-}
-
-
-// Create socket reader.
-CPjSocketReader *CPjSocket::CreateReader(unsigned max_len)
-{
-    pj_assert(sockReader_ == NULL);
-    return sockReader_ = CPjSocketReader::NewL(*this, max_len);
 }
 
@@ -164,5 +170,4 @@
     void (*old_cb)(void *key) = readCb_;
     void *old_key = key_;
-    bool is_active = IsActive();
 
     readCb_ = NULL;
Index: /pjproject/trunk/pjlib/src/pj/timer_symbian.cpp
===================================================================
--- /pjproject/trunk/pjlib/src/pj/timer_symbian.cpp	(revision 1247)
+++ /pjproject/trunk/pjlib/src/pj/timer_symbian.cpp	(revision 1248)
@@ -89,5 +89,9 @@
     CActiveScheduler::Add(this);
     
-    rtimer_.After(iStatus, PJ_TIME_VAL_MSEC(*delay) * 1000);
+    pj_int32_t interval = PJ_TIME_VAL_MSEC(*delay) * 1000;
+    if (interval < 0) {
+    	interval = 0;
+    }
+    rtimer_.After(iStatus, interval);
     SetActive();
 }
Index: /pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c	(revision 1247)
+++ /pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c	(revision 1248)
@@ -231,5 +231,5 @@
 
     /* Create transport structure */
-    pool = pjmedia_endpt_create_pool(endpt, name, 4000, 4000);
+    pool = pjmedia_endpt_create_pool(endpt, name, 512, 512);
     if (!pool)
 	return PJ_ENOMEM;
Index: /pjproject/trunk/pjnath/src/pjnath/ice_strans.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/ice_strans.c	(revision 1247)
+++ /pjproject/trunk/pjnath/src/pjnath/ice_strans.c	(revision 1248)
@@ -97,5 +97,5 @@
 	name = "icstr%p";
 
-    pool = pj_pool_create(stun_cfg->pf, name, 4000, 4000, NULL);
+    pool = pj_pool_create(stun_cfg->pf, name, 1000, 512, NULL);
     ice_st = PJ_POOL_ZALLOC_T(pool, pj_ice_strans);
     ice_st->pool = pool;
Index: /pjproject/trunk/pjsip-apps/src/symbian_ua/main_symbian.cpp
===================================================================
--- /pjproject/trunk/pjsip-apps/src/symbian_ua/main_symbian.cpp	(revision 1247)
+++ /pjproject/trunk/pjsip-apps/src/symbian_ua/main_symbian.cpp	(revision 1248)
@@ -25,53 +25,33 @@
 //  Global Variables
 CConsoleBase* console;
-static CActiveSchedulerWait *asw;
 
 
-//  Local Functions
-
-LOCAL_C void MainL()
-{
-    //
-    // add your program code here, example code below
-    //
-    int rc = ua_main();
-
-    asw->AsyncStop();
-}
-
-class MyScheduler : public CActiveScheduler
-{
-public:
-    MyScheduler()
-    {}
-
-    void Error(TInt aError) const;
-};
-
-void MyScheduler::Error(TInt aError) const
-{
-    PJ_UNUSED_ARG(aError);
-}
-
+/////////////////////////////////////
 class MyTask : public CActive
 {
 public:
-    static MyTask *NewL();
+    static MyTask *NewL(CActiveSchedulerWait *asw);
+    ~MyTask();
     void Start();
 
 protected:
-    MyTask();
+    MyTask(CActiveSchedulerWait *asw);
     void ConstructL();
     virtual void RunL();
     virtual void DoCancel();
-    TInt RunError(TInt aError);
 
 private:
     RTimer timer_;
+    CActiveSchedulerWait *asw_;
 };
 
-MyTask::MyTask()
-: CActive(EPriorityNormal)
+MyTask::MyTask(CActiveSchedulerWait *asw)
+: CActive(EPriorityNormal), asw_(asw)
 {
+}
+
+MyTask::~MyTask() 
+{
+    timer_.Close();
 }
 
@@ -82,7 +62,7 @@
 }
 
-MyTask *MyTask::NewL()
+MyTask *MyTask::NewL(CActiveSchedulerWait *asw)
 {
-    MyTask *self = new (ELeave) MyTask;
+    MyTask *self = new (ELeave) MyTask(asw);
     CleanupStack::PushL(self);
 
@@ -101,5 +81,6 @@
 void MyTask::RunL()
 {
-    MainL();
+    int rc = ua_main();
+    asw_->AsyncStop();
 }
 
@@ -108,65 +89,26 @@
 }
 
-TInt MyTask::RunError(TInt aError)
-{
-    PJ_UNUSED_ARG(aError);
-    return KErrNone;
-}
-
-
 LOCAL_C void DoStartL()
 {
-    // Create active scheduler (to run active objects)
-    MyScheduler* scheduler = new (ELeave) MyScheduler;
+    CActiveScheduler *scheduler = new (ELeave) CActiveScheduler;
     CleanupStack::PushL(scheduler);
     CActiveScheduler::Install(scheduler);
 
-    MyTask *task = MyTask::NewL();
+    CActiveSchedulerWait *asw = new CActiveSchedulerWait;
+    CleanupStack::PushL(asw);
+    
+    MyTask *task = MyTask::NewL(asw);
     task->Start();
 
-    asw = new CActiveSchedulerWait;
     asw->Start();
     
+    delete task;
+    
+    CleanupStack::Pop(asw);
     delete asw;
+    
+    CActiveScheduler::Install(NULL);
     CleanupStack::Pop(scheduler);
-}
-
-
-////////////////////////////////////////////////////////////////////////////
-
-class TMyTrapHandler : public TTrapHandler 
-{
-public:
-	void Install();
-	void Uninstall();
-	virtual IMPORT_C void Trap();
-	virtual IMPORT_C void UnTrap();
-	virtual IMPORT_C void Leave(TInt aValue);
-	
-private:
-	TTrapHandler *prev_;
-};
-
-void TMyTrapHandler::Install() {
-	prev_ = User::SetTrapHandler(this);
-}
-
-void TMyTrapHandler::Uninstall() {
-	User::SetTrapHandler(prev_);
-}
-
-IMPORT_C void TMyTrapHandler::Trap() 
-{
-	prev_->Trap();
-}
-
-IMPORT_C void TMyTrapHandler::UnTrap() 
-{
-	prev_->UnTrap();
-}
-
-IMPORT_C void TMyTrapHandler::Leave(TInt aValue) 
-{
-	prev_->Leave(aValue);
+    delete scheduler;
 }
 
@@ -177,10 +119,6 @@
 GLDEF_C TInt E32Main()
 {
-    TMyTrapHandler th;
-    
-    th.Install();
-    
     // Create cleanup stack
-    //__UHEAP_MARK;
+    __UHEAP_MARK;
     CTrapCleanup* cleanup = CTrapCleanup::New();
 
@@ -193,11 +131,11 @@
 
     console->Printf(_L("[press any key to close]\n"));
-    console->Getch();
+    //console->Getch();
     
     delete console;
     delete cleanup;
-    //__UHEAP_MARKEND;
-    
-    th.Uninstall();
+
+    CloseSTDLIB();    
+    __UHEAP_MARKEND;
     return KErrNone;
 }
Index: /pjproject/trunk/pjsip-apps/src/symbian_ua/ua.cpp
===================================================================
--- /pjproject/trunk/pjsip-apps/src/symbian_ua/ua.cpp	(revision 1247)
+++ /pjproject/trunk/pjsip-apps/src/symbian_ua/ua.cpp	(revision 1248)
@@ -47,5 +47,5 @@
 // Destination URI (to make call, or to subscribe presence)
 //
-#define SIP_DST_URI	"sip:192.168.0.70:5061"
+#define SIP_DST_URI	"sip:192.168.0.7:5061"
 
 //
@@ -53,7 +53,7 @@
 //
 #define HAS_SIP_ACCOUNT	0	// 0 to disable registration
-#define SIP_DOMAIN	"colinux"
-#define SIP_USER	"bulukucing"
-#define SIP_PASSWD	"netura"
+#define SIP_DOMAIN	"server"
+#define SIP_USER	"user"
+#define SIP_PASSWD	"password"
 
 //
@@ -61,5 +61,34 @@
 //
 #define SIP_PROXY	NULL
-//#define SIP_PROXY	"sip:192.168.0.1"
+//#define SIP_PROXY	"sip:192.168.0.8"
+
+
+//
+// Configure nameserver if DNS SRV is to be used with both SIP
+// or STUN (for STUN see other settings below)
+//
+#define NAMESERVER	NULL
+//#define NAMESERVER	"62.241.163.201"
+
+//
+// STUN server
+#if 0
+	// Use this to have the STUN server resolved normally
+#   define STUN_DOMAIN	NULL
+#   define STUN_SERVER	"stun.fwdnet.net"
+#elif 0
+	// Use this to have the STUN server resolved with DNS SRV
+#   define STUN_DOMAIN	"iptel.org"
+#   define STUN_SERVER	NULL
+#else
+	// Use this to disable STUN
+#   define STUN_DOMAIN	NULL
+#   define STUN_SERVER	NULL
+#endif
+
+//
+// Use ICE?
+//
+#define USE_ICE		1
 
 
@@ -94,6 +123,6 @@
     g_call_id = call_id;
     
-    /* Automatically answer incoming calls with 200/OK */
-    pjsua_call_answer(call_id, 200, NULL, NULL);
+    /* Automatically answer incoming calls with 180/Ringing */
+    pjsua_call_answer(call_id, 180, NULL, NULL);
 }
 
@@ -110,5 +139,5 @@
     	if (call_id == g_call_id)
     	    g_call_id = PJSUA_INVALID_ID;
-    } else {
+    } else if (ci.state != PJSIP_INV_STATE_INCOMING) {
     	if (g_call_id == PJSUA_INVALID_ID)
     	    g_call_id = call_id;
@@ -276,4 +305,16 @@
 	}
 	
+	if (NAMESERVER) {
+		cfg.nameserver_count = 1;
+		cfg.nameserver[0] = pj_str(NAMESERVER);
+	}
+	
+	if (NAMESERVER && STUN_DOMAIN) {
+		cfg.stun_domain = pj_str(STUN_DOMAIN);
+	} else if (STUN_SERVER) {
+		cfg.stun_host = pj_str(STUN_SERVER);
+	}
+	
+	
 	pjsua_logging_config_default(&log_cfg);
 	log_cfg.console_level = 4;
@@ -285,4 +326,5 @@
 	med_cfg.clock_rate = 8000;
 	med_cfg.ec_tail_len = 0;
+	med_cfg.enable_ice = USE_ICE;
 	
 	status = pjsua_init(&cfg, &log_cfg, &med_cfg);
@@ -483,4 +525,5 @@
 }
 
+
 ////////////////////////////////////////////////////////////////////////////
 int ua_main() 
@@ -492,6 +535,5 @@
 	if (status != PJ_SUCCESS)
 		return status;
-	
-	
+
 	// Run the UI
 	CActiveSchedulerWait *asw = new CActiveSchedulerWait;
Index: /pjproject/trunk/pjsip/include/pjsip/sip_transport.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 1247)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 1248)
@@ -933,4 +933,14 @@
 						  int *port);
 
+/**
+ * Return number of transports currently registered to the transport
+ * manager.
+ *
+ * @param mgr	    The transport manager.
+ *
+ * @return	    Number of transports.
+ */
+PJ_DECL(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr);
+
 
 /**
Index: /pjproject/trunk/pjsip/src/pjsip/sip_transport.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 1247)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 1248)
@@ -1012,4 +1012,26 @@
 }
 
+/*
+ * Return number of transports currently registered to the transport
+ * manager.
+ */
+PJ_DEF(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr)
+{
+    pj_hash_iterator_t itr_val;
+    pj_hash_iterator_t *itr;
+    int nr_of_transports = 0;
+    
+    pj_lock_acquire(mgr->lock);
+    
+    itr = pj_hash_first(mgr->table, &itr_val);
+    while (itr) {
+	nr_of_transports++;
+	itr = pj_hash_next(mgr->table, itr);
+    }
+    
+    pj_lock_release(mgr->lock);
+
+    return nr_of_transports;
+}
 
 /*
Index: /pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c	(revision 1247)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c	(revision 1248)
@@ -130,8 +130,11 @@
      */
     for (i=0;; ++i) {
+    	enum { MIN_SIZE = 32 };
 	pj_uint32_t flags;
 
-	/* Report the packet to transport manager. */
-	if (bytes_read > 0) {
+	/* Report the packet to transport manager. Only do so if packet size
+	 * is relatively big enough for a SIP packet.
+	 */
+	if (bytes_read > MIN_SIZE) {
 	    pj_size_t size_eaten;
 	    const pj_sockaddr_in *src_addr = 
@@ -158,5 +161,5 @@
 	    rdata->pkt_info.len = 0;
 
-	} else if (bytes_read == 0) {
+	} else if (bytes_read <= MIN_SIZE) {
 
 	    /* TODO: */
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1247)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 1248)
@@ -647,4 +647,8 @@
 {
 #if defined(PJ_SYMBIAN) && PJ_SYMBIAN != 0
+    /* Ideally we shouldn't call pj_thread_sleep() and rather
+     * CActiveScheduler::WaitForAnyRequest() here, but that will
+     * drag in Symbian header and it doesn't look pretty.
+     */
     pj_thread_sleep(msec);
 #else
@@ -976,4 +980,13 @@
 PJ_DEF(int) pjsua_handle_events(unsigned msec_timeout)
 {
+#if defined(PJ_SYMBIAN) && PJ_SYMBIAN != 0
+    /* Ideally we shouldn't call pj_thread_sleep() and rather
+     * CActiveScheduler::WaitForAnyRequest() here, but that will
+     * drag in Symbian header and it doesn't look pretty.
+     */
+    pj_thread_sleep(msec_timeout);
+    return msec_timeout;
+#else
+
     unsigned count = 0;
     pj_time_val tv;
@@ -990,4 +1003,5 @@
 
     return count;
+#endif
 }
 
