Misc Symbian fixes, looks good

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1248 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/build.symbian/pjmedia.mmp b/build.symbian/pjmedia.mmp
index f9bd56a..7af3187 100644
--- a/build.symbian/pjmedia.mmp
+++ b/build.symbian/pjmedia.mmp
@@ -46,6 +46,7 @@
 SOURCE		sound_port.c

 SOURCE		splitcomb.c

 SOURCE		stream.c

+SOURCE		tonegen.c

 SOURCE		transport_ice.c

 SOURCE		transport_udp.c

 SOURCE		wav_player.c

diff --git a/build.symbian/pjproject.cww b/build.symbian/pjproject.cww
index 81efe19..847bb94 100644
--- a/build.symbian/pjproject.cww
+++ b/build.symbian/pjproject.cww
@@ -271,8 +271,8 @@
             <Y>4</Y>

         </FRAMELOC>

         <FRAMESIZE>

-            <W>605</W>

-            <H>778</H>

+            <W>629</W>

+            <H>859</H>

         </FRAMESIZE>

         <DOCKINFO>

             <STATUS>0</STATUS>

@@ -296,8 +296,8 @@
             <Y>23</Y>

         </FRAMELOC>

         <FRAMESIZE>

-            <W>470</W>

-            <H>705</H>

+            <W>534</W>

+            <H>921</H>

         </FRAMESIZE>

         <DOCKINFO>

             <STATUS>0</STATUS>

@@ -321,8 +321,8 @@
             <Y>23</Y>

         </FRAMELOC>

         <FRAMESIZE>

-            <W>904</W>

-            <H>1791</H>

+            <W>1008</W>

+            <H>2142</H>

         </FRAMESIZE>

         <DOCKINFO>

             <STATUS>0</STATUS>

@@ -340,7 +340,6 @@
     <WINDOW>

         <SESSION>-2147483648</SESSION>

         <EDOCTYPE>23</EDOCTYPE>

-        <MAXIMIZED>true</MAXIMIZED>

         <FRAMELOC>

             <X>6</X>

             <Y>81</Y>

diff --git a/pjlib/src/pj/ioqueue_symbian.cpp b/pjlib/src/pj/ioqueue_symbian.cpp
index 6768cc0..73f0f04 100644
--- a/pjlib/src/pj/ioqueue_symbian.cpp
+++ b/pjlib/src/pj/ioqueue_symbian.cpp
@@ -648,6 +648,10 @@
 				     pj_ssize_t *length,
 				     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;
     return key->cbObj->StartRead(op_key, buffer, length, flags, NULL, NULL);
@@ -667,6 +671,10 @@
 					 pj_sockaddr_t *addr,
 					 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;
 
diff --git a/pjlib/src/pj/os_core_symbian.cpp b/pjlib/src/pj/os_core_symbian.cpp
index a55b548..742fe5a 100644
--- a/pjlib/src/pj/os_core_symbian.cpp
+++ b/pjlib/src/pj/os_core_symbian.cpp
@@ -421,6 +421,11 @@
 PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
 {
     User::After(msec*1000);
+    
+    TInt aError;
+    while (CActiveScheduler::RunIfReady(aError, EPriorityMuchLess))
+    	;
+    
     return PJ_SUCCESS;
 }
 
diff --git a/pjlib/src/pj/os_symbian.h b/pjlib/src/pj/os_symbian.h
index 929070b..a197787 100644
--- a/pjlib/src/pj/os_symbian.h
+++ b/pjlib/src/pj/os_symbian.h
@@ -86,6 +86,9 @@
     // Create socket reader.
     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
 				    // it may point to local variable!
@@ -187,11 +190,6 @@
 {
 public:
     //
-    // Construct PjSymbianOS instance.
-    //
-    static PjSymbianOS *NewL();
-
-    //
     // Get the singleton instance of PjSymbianOS
     //
     static PjSymbianOS *Instance();
diff --git a/pjlib/src/pj/sock_symbian.cpp b/pjlib/src/pj/sock_symbian.cpp
index 8d2ab07..ae691ba 100644
--- a/pjlib/src/pj/sock_symbian.cpp
+++ b/pjlib/src/pj/sock_symbian.cpp
@@ -66,12 +66,7 @@
 
 CPjSocket::~CPjSocket()
 {
-    if (sockReader_) {
-	if (sockReader_->IsActive())
-	    sockReader_->Cancel();
-	delete sockReader_;
-	sockReader_ = NULL;
-    }
+    DestroyReader();
     sock_.Close();
 }
 
@@ -83,6 +78,17 @@
     return sockReader_ = CPjSocketReader::NewL(*this, max_len);
 }
 
+// Delete socket reader when it's not wanted.
+void CPjSocket::DestroyReader() 
+{
+    if (sockReader_) {
+	if (sockReader_->IsActive())
+	    sockReader_->Cancel();
+	delete sockReader_;
+	sockReader_ = NULL;
+    }
+}
+
 
 /////////////////////////////////////////////////////////////////////////////
 //
@@ -163,7 +169,6 @@
 {
     void (*old_cb)(void *key) = readCb_;
     void *old_key = key_;
-    bool is_active = IsActive();
 
     readCb_ = NULL;
     key_ = NULL;
diff --git a/pjlib/src/pj/timer_symbian.cpp b/pjlib/src/pj/timer_symbian.cpp
index 398f772..eaf4f9e 100644
--- a/pjlib/src/pj/timer_symbian.cpp
+++ b/pjlib/src/pj/timer_symbian.cpp
@@ -88,7 +88,11 @@
     rtimer_.CreateLocal();
     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();
 }
 
diff --git a/pjmedia/src/pjmedia/transport_udp.c b/pjmedia/src/pjmedia/transport_udp.c
index 2bf570e..a8576a7 100644
--- a/pjmedia/src/pjmedia/transport_udp.c
+++ b/pjmedia/src/pjmedia/transport_udp.c
@@ -230,7 +230,7 @@
 
 
     /* 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;
 
diff --git a/pjnath/src/pjnath/ice_strans.c b/pjnath/src/pjnath/ice_strans.c
index a7e5f8f..16e8e96 100644
--- a/pjnath/src/pjnath/ice_strans.c
+++ b/pjnath/src/pjnath/ice_strans.c
@@ -96,7 +96,7 @@
     if (name == NULL)
 	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;
     pj_memcpy(ice_st->obj_name, pool->obj_name, PJ_MAX_OBJ_NAME);
diff --git a/pjsip-apps/src/symbian_ua/main_symbian.cpp b/pjsip-apps/src/symbian_ua/main_symbian.cpp
index 640fb2d..cdfcd9f 100644
--- a/pjsip-apps/src/symbian_ua/main_symbian.cpp
+++ b/pjsip-apps/src/symbian_ua/main_symbian.cpp
@@ -24,66 +24,46 @@
 
 //  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();
+}
+
 void MyTask::ConstructL()
 {
     timer_.CreateLocal();
     CActiveScheduler::Add(this);
 }
 
-MyTask *MyTask::NewL()
+MyTask *MyTask::NewL(CActiveSchedulerWait *asw)
 {
-    MyTask *self = new (ELeave) MyTask;
+    MyTask *self = new (ELeave) MyTask(asw);
     CleanupStack::PushL(self);
 
     self->ConstructL();
@@ -100,74 +80,36 @@
 
 void MyTask::RunL()
 {
-    MainL();
+    int rc = ua_main();
+    asw_->AsyncStop();
 }
 
 void MyTask::DoCancel()
 {
 }
 
-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;
 }
 
 
@@ -176,12 +118,8 @@
 //  Global Functions
 GLDEF_C TInt E32Main()
 {
-    TMyTrapHandler th;
-    
-    th.Install();
-    
     // Create cleanup stack
-    //__UHEAP_MARK;
+    __UHEAP_MARK;
     CTrapCleanup* cleanup = CTrapCleanup::New();
 
     // Create output console
@@ -192,13 +130,13 @@
     TRAPD(startError, DoStartL());
 
     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;
 }
 
diff --git a/pjsip-apps/src/symbian_ua/ua.cpp b/pjsip-apps/src/symbian_ua/ua.cpp
index ee84eaf..cc59091 100644
--- a/pjsip-apps/src/symbian_ua/ua.cpp
+++ b/pjsip-apps/src/symbian_ua/ua.cpp
@@ -46,21 +46,50 @@
 //
 // 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"
 
 //
 // Account
 //
 #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"
 
 //
 // Outbound proxy for all accounts
 //
 #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
 
 
 //
@@ -93,8 +122,8 @@
 
     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);
 }
 
 /* Callback called by the library when call's state has changed */
@@ -109,7 +138,7 @@
     if (ci.state == PJSIP_INV_STATE_DISCONNECTED) {
     	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;
     }
@@ -275,6 +304,18 @@
 		cfg.outbound_proxy[0] = pj_str(SIP_PROXY);
 	}
 	
+	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;
 	log_cfg.cb = &log_writer;
@@ -284,6 +325,7 @@
 	med_cfg.has_ioqueue = PJ_FALSE;
 	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);
 	if (status != PJ_SUCCESS) {
@@ -482,6 +524,7 @@
 		Run();
 }
 
+
 ////////////////////////////////////////////////////////////////////////////
 int ua_main() 
 {
@@ -491,8 +534,7 @@
 	status  = app_startup();
 	if (status != PJ_SUCCESS)
 		return status;
-	
-	
+
 	// Run the UI
 	CActiveSchedulerWait *asw = new CActiveSchedulerWait;
 	ConsoleUI *con = new ConsoleUI(asw, console);
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h
index a9be172..5137ef7 100644
--- a/pjsip/include/pjsip/sip_transport.h
+++ b/pjsip/include/pjsip/sip_transport.h
@@ -932,6 +932,16 @@
 						  pj_str_t *ip_addr,
 						  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);
+
 
 /**
  * Destroy transport manager.
diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
index ee42699..afe0f1e 100644
--- a/pjsip/src/pjsip/sip_transport.c
+++ b/pjsip/src/pjsip/sip_transport.c
@@ -1011,6 +1011,28 @@
     return PJ_SUCCESS;
 }
 
+/*
+ * 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;
+}
 
 /*
  * pjsip_tpmgr_destroy()
diff --git a/pjsip/src/pjsip/sip_transport_udp.c b/pjsip/src/pjsip/sip_transport_udp.c
index 42e001d..02b86fb 100644
--- a/pjsip/src/pjsip/sip_transport_udp.c
+++ b/pjsip/src/pjsip/sip_transport_udp.c
@@ -129,10 +129,13 @@
      * complete asynchronously, to allow other sockets to get their data.
      */
     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 = 
 		(pj_sockaddr_in*)&rdata->pkt_info.src_addr;
@@ -157,7 +160,7 @@
 	    /* Since this is UDP, the whole buffer is the message. */
 	    rdata->pkt_info.len = 0;
 
-	} else if (bytes_read == 0) {
+	} else if (bytes_read <= MIN_SIZE) {
 
 	    /* TODO: */
 
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 3469153..162d2da 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -646,6 +646,10 @@
 static void busy_sleep(unsigned msec)
 {
 #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
     pj_time_val timeout, now;
@@ -975,6 +979,15 @@
  */
 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;
     pj_status_t status;
@@ -989,6 +1002,7 @@
 	return -status;
 
     return count;
+#endif
 }