summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-05-03 13:31:21 +0000
committerBenny Prijono <bennylp@teluu.com>2007-05-03 13:31:21 +0000
commit8f426164cc8b5ca4ea96766bf78fd2d1f28cd656 (patch)
tree8588997230cc891c042cd63ba187bb10585e20da
parent3d5dfee8ad79256ed558c7c46ebde8849321c3ae (diff)
Implemented ticket #246, #247, #261, #268, #250 for Symbian
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1246 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--build.symbian/pjlib.mmp6
-rw-r--r--build.symbian/pjlib_util.mmp1
-rw-r--r--build.symbian/pjproject.cww222
-rw-r--r--build.symbian/symbian_ua.mmp4
-rw-r--r--pjlib/include/pj/compat/cc_armcc.h50
-rw-r--r--pjlib/include/pj/compat/cc_gcce.h51
-rw-r--r--pjlib/include/pj/config.h4
-rw-r--r--pjlib/include/pj/timer.h4
-rw-r--r--pjlib/src/pj/guid_simple.c4
-rw-r--r--pjlib/src/pj/ioqueue_symbian.cpp46
-rw-r--r--pjlib/src/pj/os_core_symbian.cpp8
-rw-r--r--pjlib/src/pj/os_symbian.h15
-rw-r--r--pjlib/src/pj/sock_symbian.cpp31
-rw-r--r--pjlib/src/pj/timer_symbian.cpp272
-rw-r--r--pjsip-apps/src/symbian_ua/ua.cpp198
-rw-r--r--pjsip/src/pjsip/sip_transaction.c75
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c4
17 files changed, 690 insertions, 305 deletions
diff --git a/build.symbian/pjlib.mmp b/build.symbian/pjlib.mmp
index 1e52ba4f..8ec56ca7 100644
--- a/build.symbian/pjlib.mmp
+++ b/build.symbian/pjlib.mmp
@@ -30,18 +30,19 @@ SOURCE pool_buf.c
SOURCE pool_caching.c
SOURCE rand.c
SOURCE rbtree.c
-SOURCE timer.c
SOURCE types.c
//
// Platform dependent source
//
+SOURCE compat\string_compat.c
SOURCE addr_resolv_symbian.cpp
SOURCE exception_symbian.cpp
SOURCE file_access_unistd.c
SOURCE file_io_ansi.c
SOURCE guid_simple.c
+SOURCE ioqueue_symbian.cpp
SOURCE ip_helper_generic.c
SOURCE log_writer_symbian_console.cpp
SOURCE os_core_symbian.cpp
@@ -50,10 +51,9 @@ SOURCE os_timestamp_common.c
SOURCE os_time_unix.c
SOURCE os_timestamp_posix.c
SOURCE pool_policy_new.cpp
-SOURCE compat\string_compat.c
SOURCE sock_symbian.cpp
SOURCE sock_select_symbian.cpp
-SOURCE ioqueue_symbian.cpp
+SOURCE timer_symbian.cpp
SOURCE unicode_symbian.cpp
DOCUMENT os_symbian.h
diff --git a/build.symbian/pjlib_util.mmp b/build.symbian/pjlib_util.mmp
index 9315d730..30f59fa2 100644
--- a/build.symbian/pjlib_util.mmp
+++ b/build.symbian/pjlib_util.mmp
@@ -57,6 +57,5 @@ SYSTEMINCLUDE ..\pjlib-util\include
SYSTEMINCLUDE \epoc32\include
SYSTEMINCLUDE \epoc32\include\libc
-LIBRARY pjlib.lib
CAPABILITY None
diff --git a/build.symbian/pjproject.cww b/build.symbian/pjproject.cww
index f30e19fa..81efe194 100644
--- a/build.symbian/pjproject.cww
+++ b/build.symbian/pjproject.cww
@@ -164,14 +164,14 @@
<WINDOW>
<SESSION>-1</SESSION>
<EDOCTYPE>0</EDOCTYPE>
- <PATH USERELATIVEPATHS = "true">pjsua_lib.mcp</PATH>
+ <PATH USERELATIVEPATHS = "true">pjsip_ua.mcp</PATH>
<FRAMELOC>
- <X>634</X>
- <Y>231</Y>
+ <X>548</X>
+ <Y>123</Y>
</FRAMELOC>
<FRAMESIZE>
- <W>347</W>
- <H>128</H>
+ <W>400</W>
+ <H>372</H>
</FRAMESIZE>
<DOCKINFO>
<STATUS>1</STATUS>
@@ -189,10 +189,10 @@
<WINDOW>
<SESSION>-1</SESSION>
<EDOCTYPE>0</EDOCTYPE>
- <PATH USERELATIVEPATHS = "true">symbian_ua.mcp</PATH>
+ <PATH USERELATIVEPATHS = "true">pjsip_simple.mcp</PATH>
<FRAMELOC>
- <X>571</X>
- <Y>149</Y>
+ <X>0</X>
+ <Y>0</Y>
</FRAMELOC>
<FRAMESIZE>
<W>347</W>
@@ -213,51 +213,51 @@
</WINDOW>
<WINDOW>
<SESSION>-1</SESSION>
- <EDOCTYPE>1</EDOCTYPE>
- <PATH USERELATIVEPATHS = "true">..\pjlib\src\pj\sock_symbian.cpp</PATH>
+ <EDOCTYPE>0</EDOCTYPE>
+ <PATH USERELATIVEPATHS = "true">pjsua_lib.mcp</PATH>
<FRAMELOC>
- <X>8</X>
- <Y>27</Y>
+ <X>634</X>
+ <Y>231</Y>
</FRAMELOC>
<FRAMESIZE>
- <W>646</W>
- <H>464</H>
+ <W>347</W>
+ <H>128</H>
</FRAMESIZE>
<DOCKINFO>
- <STATUS>0</STATUS>
- <ROW></ROW>
- <COLUMN></COLUMN>
- <DOCKBARID></DOCKBARID>
- <PCTWIDTH></PCTWIDTH>
- <HGT></HGT>
+ <STATUS>1</STATUS>
+ <ROW>0</ROW>
+ <COLUMN>0</COLUMN>
+ <DOCKBARID>59420</DOCKBARID>
+ <PCTWIDTH>1.000000</PCTWIDTH>
+ <HGT>294</HGT>
<GROUPID>
- <GIDHIGHPART></GIDHIGHPART>
- <GIDLOWPART></GIDLOWPART>
+ <GIDHIGHPART>4294967294</GIDHIGHPART>
+ <GIDLOWPART>4294967294</GIDLOWPART>
</GROUPID>
</DOCKINFO>
</WINDOW>
<WINDOW>
<SESSION>-1</SESSION>
- <EDOCTYPE>1</EDOCTYPE>
- <PATH USERELATIVEPATHS = "true">..\pjsip-apps\src\symbian_ua\main_symbian.cpp</PATH>
+ <EDOCTYPE>0</EDOCTYPE>
+ <PATH USERELATIVEPATHS = "true">symbian_ua.mcp</PATH>
<FRAMELOC>
- <X>8</X>
- <Y>27</Y>
+ <X>571</X>
+ <Y>149</Y>
</FRAMELOC>
<FRAMESIZE>
- <W>638</W>
- <H>437</H>
+ <W>347</W>
+ <H>128</H>
</FRAMESIZE>
<DOCKINFO>
- <STATUS>0</STATUS>
- <ROW></ROW>
- <COLUMN></COLUMN>
- <DOCKBARID></DOCKBARID>
- <PCTWIDTH></PCTWIDTH>
- <HGT></HGT>
+ <STATUS>1</STATUS>
+ <ROW>0</ROW>
+ <COLUMN>0</COLUMN>
+ <DOCKBARID>59420</DOCKBARID>
+ <PCTWIDTH>1.000000</PCTWIDTH>
+ <HGT>294</HGT>
<GROUPID>
- <GIDHIGHPART></GIDHIGHPART>
- <GIDLOWPART></GIDLOWPART>
+ <GIDHIGHPART>4294967294</GIDHIGHPART>
+ <GIDLOWPART>4294967294</GIDLOWPART>
</GROUPID>
</DOCKINFO>
</WINDOW>
@@ -265,138 +265,14 @@
<SESSION>-1</SESSION>
<EDOCTYPE>1</EDOCTYPE>
<PATH USERELATIVEPATHS = "true">..\pjsip-apps\src\symbian_ua\ua.cpp</PATH>
- <FRAMELOC>
- <X>4</X>
- <Y>23</Y>
- </FRAMELOC>
- <FRAMESIZE>
- <W>565</W>
- <H>643</H>
- </FRAMESIZE>
- <DOCKINFO>
- <STATUS>0</STATUS>
- <ROW></ROW>
- <COLUMN></COLUMN>
- <DOCKBARID></DOCKBARID>
- <PCTWIDTH></PCTWIDTH>
- <HGT></HGT>
- <GROUPID>
- <GIDHIGHPART></GIDHIGHPART>
- <GIDLOWPART></GIDLOWPART>
- </GROUPID>
- </DOCKINFO>
- </WINDOW>
- <WINDOW>
- <SESSION>-1</SESSION>
- <EDOCTYPE>1</EDOCTYPE>
- <PATH USERELATIVEPATHS = "true">..\pjlib\src\pj\ioqueue_symbian.cpp</PATH>
- <FRAMELOC>
- <X>10</X>
- <Y>40</Y>
- </FRAMELOC>
- <FRAMESIZE>
- <W>630</W>
- <H>410</H>
- </FRAMESIZE>
- <DOCKINFO>
- <STATUS>0</STATUS>
- <ROW></ROW>
- <COLUMN></COLUMN>
- <DOCKBARID></DOCKBARID>
- <PCTWIDTH></PCTWIDTH>
- <HGT></HGT>
- <GROUPID>
- <GIDHIGHPART></GIDHIGHPART>
- <GIDLOWPART></GIDLOWPART>
- </GROUPID>
- </DOCKINFO>
- </WINDOW>
- <WINDOW>
- <SESSION>-1</SESSION>
- <EDOCTYPE>1</EDOCTYPE>
- <PATH USERELATIVEPATHS = "true">..\pjlib\src\pj\os_core_symbian.cpp</PATH>
- <FRAMELOC>
- <X>6</X>
- <Y>23</Y>
- </FRAMELOC>
- <FRAMESIZE>
- <W>638</W>
- <H>437</H>
- </FRAMESIZE>
- <DOCKINFO>
- <STATUS>0</STATUS>
- <ROW></ROW>
- <COLUMN></COLUMN>
- <DOCKBARID></DOCKBARID>
- <PCTWIDTH></PCTWIDTH>
- <HGT></HGT>
- <GROUPID>
- <GIDHIGHPART></GIDHIGHPART>
- <GIDLOWPART></GIDLOWPART>
- </GROUPID>
- </DOCKINFO>
- </WINDOW>
- <WINDOW>
- <SESSION>-1</SESSION>
- <EDOCTYPE>1</EDOCTYPE>
- <PATH USERELATIVEPATHS = "true">..\pjlib\src\pj\os_error_symbian.cpp</PATH>
- <FRAMELOC>
- <X>8</X>
- <Y>27</Y>
- </FRAMELOC>
- <FRAMESIZE>
- <W>638</W>
- <H>437</H>
- </FRAMESIZE>
- <DOCKINFO>
- <STATUS>0</STATUS>
- <ROW></ROW>
- <COLUMN></COLUMN>
- <DOCKBARID></DOCKBARID>
- <PCTWIDTH></PCTWIDTH>
- <HGT></HGT>
- <GROUPID>
- <GIDHIGHPART></GIDHIGHPART>
- <GIDLOWPART></GIDLOWPART>
- </GROUPID>
- </DOCKINFO>
- </WINDOW>
- <WINDOW>
- <SESSION>-1</SESSION>
- <EDOCTYPE>1</EDOCTYPE>
- <PATH USERELATIVEPATHS = "true">..\pjlib\src\pj\errno.c</PATH>
- <FRAMELOC>
- <X>4</X>
- <Y>23</Y>
- </FRAMELOC>
- <FRAMESIZE>
- <W>646</W>
- <H>464</H>
- </FRAMESIZE>
- <DOCKINFO>
- <STATUS>0</STATUS>
- <ROW></ROW>
- <COLUMN></COLUMN>
- <DOCKBARID></DOCKBARID>
- <PCTWIDTH></PCTWIDTH>
- <HGT></HGT>
- <GROUPID>
- <GIDHIGHPART></GIDHIGHPART>
- <GIDLOWPART></GIDLOWPART>
- </GROUPID>
- </DOCKINFO>
- </WINDOW>
- <WINDOW>
- <SESSION>-1</SESSION>
- <EDOCTYPE>20</EDOCTYPE>
<MAXIMIZED>true</MAXIMIZED>
<FRAMELOC>
- <X>0</X>
- <Y>0</Y>
+ <X>4</X>
+ <Y>4</Y>
</FRAMELOC>
<FRAMESIZE>
- <W>824</W>
- <H>1521</H>
+ <W>605</W>
+ <H>778</H>
</FRAMESIZE>
<DOCKINFO>
<STATUS>0</STATUS>
@@ -410,10 +286,6 @@
<GIDLOWPART></GIDLOWPART>
</GROUPID>
</DOCKINFO>
- <SYMBOLICSWINSETTINGS EXECUTABLEPATH = "C:\Symbian\9.1\S60_3rd_MR_2\EPOC32\RELEASE\WINSCW\UDEB\euser.dll" MACHINENAME = "Local Windows PC"/>
- <SYMBOLICSWINSETTINGS EXECUTABLEPATH = "C:\Symbian\9.1\S60_3rd_MR_2\EPOC32\RELEASE\WINSCW\UDEB\ekern.exe" MACHINENAME = "Local Windows PC"/>
- <SYMBOLICSWINSETTINGS EXECUTABLEPATH = "C:\WINNT\system32\ntdll.dll" MACHINENAME = "Local Windows PC"/>
- <SYMBOLICSWINSETTINGS EXECUTABLEPATH = "C:\Symbian\9.1\S60_3rd_MR_2\EPOC32\RELEASE\WINSCW\UDEB\econs.dll" MACHINENAME = "Local Windows PC"/>
</WINDOW>
<WINDOW>
<SESSION>-2147483648</SESSION>
@@ -424,8 +296,8 @@
<Y>23</Y>
</FRAMELOC>
<FRAMESIZE>
- <W>390</W>
- <H>435</H>
+ <W>470</W>
+ <H>705</H>
</FRAMESIZE>
<DOCKINFO>
<STATUS>0</STATUS>
@@ -449,8 +321,8 @@
<Y>23</Y>
</FRAMELOC>
<FRAMESIZE>
- <W>816</W>
- <H>1494</H>
+ <W>904</W>
+ <H>1791</H>
</FRAMESIZE>
<DOCKINFO>
<STATUS>0</STATUS>
@@ -464,15 +336,11 @@
<GIDLOWPART></GIDLOWPART>
</GROUPID>
</DOCKINFO>
- <SYMBOLICSWINSETTINGS EXECUTABLEPATH = "C:\Symbian\9.1\S60_3rd_MR_2\EPOC32\RELEASE\WINSCW\UDEB\euser.dll" MACHINENAME = "Local Windows PC"/>
- <SYMBOLICSWINSETTINGS EXECUTABLEPATH = "C:\Symbian\9.1\S60_3rd_MR_2\EPOC32\RELEASE\WINSCW\UDEB\ekern.exe" MACHINENAME = "Local Windows PC"/>
- <SYMBOLICSWINSETTINGS EXECUTABLEPATH = "C:\WINNT\system32\ntdll.dll" MACHINENAME = "Local Windows PC"/>
- <SYMBOLICSWINSETTINGS EXECUTABLEPATH = "C:\Symbian\9.1\S60_3rd_MR_2\EPOC32\RELEASE\WINSCW\UDEB\econs.dll" MACHINENAME = "Local Windows PC"/>
</WINDOW>
<WINDOW>
<SESSION>-2147483648</SESSION>
<EDOCTYPE>23</EDOCTYPE>
- <DEFAULT>true</DEFAULT>
+ <MAXIMIZED>true</MAXIMIZED>
<FRAMELOC>
<X>6</X>
<Y>81</Y>
diff --git a/build.symbian/symbian_ua.mmp b/build.symbian/symbian_ua.mmp
index 8531cb00..0c53eda1 100644
--- a/build.symbian/symbian_ua.mmp
+++ b/build.symbian/symbian_ua.mmp
@@ -24,7 +24,7 @@ SYSTEMINCLUDE ..\pjsip\include
SYSTEMINCLUDE \epoc32\include
SYSTEMINCLUDE \epoc32\include\libc
-LIBRARY pjsua_lib.lib pjsip_ua.lib pjsip_simple.lib pjsip.lib pjsdp.lib pjmedia.lib pjnath.lib pjlib_util.lib pjlib.lib esock.lib insock.lib charconv.lib euser.lib estlib.lib eexe.lib
-STATICLIBRARY ecrt0.lib
+LIBRARY esock.lib insock.lib charconv.lib euser.lib estlib.lib eexe.lib
+STATICLIBRARY pjsua_lib.lib pjsip_ua.lib pjsip_simple.lib pjsip.lib pjsdp.lib pjmedia.lib pjnath.lib pjlib_util.lib pjlib.lib ecrt0.lib
CAPABILITY None
diff --git a/pjlib/include/pj/compat/cc_armcc.h b/pjlib/include/pj/compat/cc_armcc.h
new file mode 100644
index 00000000..504ca889
--- /dev/null
+++ b/pjlib/include/pj/compat/cc_armcc.h
@@ -0,0 +1,50 @@
+/* $Id$ */
+/*
+ * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJ_COMPAT_CC_ARMCC_H__
+#define __PJ_COMPAT_CC_ARMCC_H__
+
+/**
+ * @file cc_armcc.h
+ * @brief Describes ARMCC compiler specifics.
+ */
+
+#ifndef __ARMCC__
+# error "This file is only for armcc!"
+#endif
+
+#define PJ_CC_NAME "armcc"
+#define PJ_CC_VER_1 __ARMCC__
+#define PJ_CC_VER_2 __ARMCC_MINOR__
+#define PJ_CC_VER_3 __ARMCC_PATCHLEVEL__
+
+
+#define PJ_INLINE_SPECIFIER static // why is not inline accepted?
+#define PJ_THREAD_FUNC
+#define PJ_NORETURN
+#define PJ_ATTR_NORETURN __attribute__ ((noreturn))
+
+#define PJ_HAS_INT64 1
+
+typedef long long pj_int64_t;
+typedef unsigned long long pj_uint64_t;
+
+#define PJ_INT64_FMT "L"
+
+#endif /* __PJ_COMPAT_CC_ARMCC_H__ */
+
diff --git a/pjlib/include/pj/compat/cc_gcce.h b/pjlib/include/pj/compat/cc_gcce.h
new file mode 100644
index 00000000..d27dd2c2
--- /dev/null
+++ b/pjlib/include/pj/compat/cc_gcce.h
@@ -0,0 +1,51 @@
+/* $Id$ */
+/*
+ * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJ_COMPAT_CC_GCCE_H__
+#define __PJ_COMPAT_CC_GCCE_H__
+
+/**
+ * @file cc_gcce.h
+ * @brief Describes GCCE compiler specifics.
+ */
+
+#ifndef __GCCE__
+# error "This file is only for gcce!"
+#endif
+
+#define PJ_CC_NAME "gcce"
+#define PJ_CC_VER_1 __GCCE__
+#define PJ_CC_VER_2 __GCCE_MINOR__
+#define PJ_CC_VER_3 __GCCE_PATCHLEVEL__
+
+
+#define PJ_INLINE_SPECIFIER static inline
+#define PJ_THREAD_FUNC
+#define PJ_NORETURN
+#define PJ_ATTR_NORETURN __attribute__ ((noreturn))
+
+#define PJ_HAS_INT64 1
+
+typedef long long pj_int64_t;
+typedef unsigned long long pj_uint64_t;
+
+#define PJ_INT64_FMT "L"
+
+
+#endif /* __PJ_COMPAT_CC_GCCE_H__ */
+
diff --git a/pjlib/include/pj/config.h b/pjlib/include/pj/config.h
index 197e525c..c999bb87 100644
--- a/pjlib/include/pj/config.h
+++ b/pjlib/include/pj/config.h
@@ -35,6 +35,10 @@
# include <pj/compat/cc_mwcc.h>
#elif defined(__MWERKS__)
# include <pj/compat/cc_codew.h>
+#elif defined(__GCCE__)
+# include <pj/compat/cc_gcce.h>
+#elif defined(__ARMCC__)
+# include <pj/compat/cc_armcc.h>
#else
# error "Unknown compiler."
#endif
diff --git a/pjlib/include/pj/timer.h b/pjlib/include/pj/timer.h
index cf3d1d79..6e4839c2 100644
--- a/pjlib/include/pj/timer.h
+++ b/pjlib/include/pj/timer.h
@@ -64,7 +64,11 @@ PJ_BEGIN_DECL
/**
* The type for internal timer ID.
*/
+#if defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
+typedef void *pj_timer_id_t;
+#else
typedef int pj_timer_id_t;
+#endif
/**
* Forward declaration for pj_timer_entry.
diff --git a/pjlib/src/pj/guid_simple.c b/pjlib/src/pj/guid_simple.c
index 05744bc9..fecdd78f 100644
--- a/pjlib/src/pj/guid_simple.c
+++ b/pjlib/src/pj/guid_simple.c
@@ -57,8 +57,8 @@ PJ_DEF(pj_str_t*) pj_generate_unique_string(pj_str_t *str)
}
strcpy(str->ptr, str_pid);
- sprintf(str->ptr+4, "%04x", clock_seq++);
- pj_memcpy(str->ptr+8, str_mac_addr, 12);
+ sprintf(str->ptr+4, "%08x", clock_seq++);
+ pj_memcpy(str->ptr+12, str_mac_addr, 8);
str->slen = 20;
return str;
diff --git a/pjlib/src/pj/ioqueue_symbian.cpp b/pjlib/src/pj/ioqueue_symbian.cpp
index df1fa46c..6768cc01 100644
--- a/pjlib/src/pj/ioqueue_symbian.cpp
+++ b/pjlib/src/pj/ioqueue_symbian.cpp
@@ -34,7 +34,6 @@ class CIoqueueCallback;
struct pj_ioqueue_t
{
int eventCount;
- CPjTimeoutTimer *timeoutTimer;
};
@@ -438,8 +437,7 @@ PJ_DEF(pj_status_t) pj_ioqueue_create( pj_pool_t *pool,
PJ_UNUSED_ARG(max_fd);
- ioq = (pj_ioqueue_t*) pj_pool_zalloc(pool, sizeof(pj_ioqueue_t));
- ioq->timeoutTimer = CPjTimeoutTimer::NewL();
+ ioq = PJ_POOL_ZALLOC_T(pool, pj_ioqueue_t);
*p_ioqueue = ioq;
return PJ_SUCCESS;
}
@@ -450,9 +448,7 @@ PJ_DEF(pj_status_t) pj_ioqueue_create( pj_pool_t *pool,
*/
PJ_DEF(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioq )
{
- delete ioq->timeoutTimer;
- ioq->timeoutTimer = NULL;
-
+ PJ_UNUSED_ARG(ioq);
return PJ_SUCCESS;
}
@@ -487,7 +483,7 @@ PJ_DEF(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,
{
pj_ioqueue_key_t *key;
- key = (pj_ioqueue_key_t*) pj_pool_zalloc(pool, sizeof(pj_ioqueue_key_t));
+ key = PJ_POOL_ZALLOC_T(pool, pj_ioqueue_key_t);
key->cbObj = CIoqueueCallback::NewL(ioq, key, sock, cb, user_data);
*p_key = key;
@@ -552,7 +548,7 @@ PJ_DEF(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,
PJ_DEF(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,
pj_size_t size )
{
- pj_memset(op_key, 0, size);
+ pj_bzero(op_key, size);
}
@@ -634,34 +630,12 @@ PJ_DEF(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,
PJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioq,
const pj_time_val *timeout)
{
- CPjTimeoutTimer *timer;
-
- if (timeout) {
- //if (!ioq->timeoutTimer->IsActive())
- if (0)
- timer = ioq->timeoutTimer;
- else
- timer = CPjTimeoutTimer::NewL();
-
- timer->StartTimer(timeout->sec*1000 + timeout->msec);
-
- } else {
- timer = NULL;
- }
-
- ioq->eventCount = 0;
-
- do {
- PjSymbianOS::Instance()->WaitForActiveObjects();
- } while (ioq->eventCount == 0 && (!timer || (timer && !timer->HasTimedOut())));
-
- if (timer && !timer->HasTimedOut())
- timer->Cancel();
-
- if (timer && timer != ioq->timeoutTimer)
- delete timer;
-
- return ioq->eventCount;
+ /* Polling is not necessary on Symbian, since all async activities
+ * are registered to active scheduler.
+ */
+ PJ_UNUSED_ARG(ioq);
+ PJ_UNUSED_ARG(timeout);
+ return 0;
}
diff --git a/pjlib/src/pj/os_core_symbian.cpp b/pjlib/src/pj/os_core_symbian.cpp
index d0bbb157..a55b548a 100644
--- a/pjlib/src/pj/os_core_symbian.cpp
+++ b/pjlib/src/pj/os_core_symbian.cpp
@@ -83,7 +83,7 @@ static void (*atexit_func[32])(void);
//
CPjTimeoutTimer::CPjTimeoutTimer()
-: CActive(EPriorityNormal), hasTimedOut_(PJ_FALSE)
+: CActive(PJ_SYMBIAN_TIMER_PRIORITY), hasTimedOut_(PJ_FALSE)
{
}
@@ -420,13 +420,7 @@ PJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *rec)
*/
PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
{
- //Not a good idea, as we don't want network events to
- //arrive while we're not polling them:
- //PjSymbianOS::Instance()->WaitForActiveObjects();
-
- //.. so rather use this, which won't wake up Active Objects:
User::After(msec*1000);
-
return PJ_SUCCESS;
}
diff --git a/pjlib/src/pj/os_symbian.h b/pjlib/src/pj/os_symbian.h
index 06973104..929070b3 100644
--- a/pjlib/src/pj/os_symbian.h
+++ b/pjlib/src/pj/os_symbian.h
@@ -20,6 +20,7 @@
#define __OS_SYMBIAN_H__
#include <pj/sock.h>
+#include <pj/string.h>
#include <e32base.h>
#include <e32cmn.h>
@@ -33,6 +34,10 @@
// Forward declarations
class CPjSocketReader;
+#ifndef PJ_SYMBIAN_TIMER_PRIORITY
+# define PJ_SYMBIAN_TIMER_PRIORITY EPriorityNormal
+#endif
+
//
// PJLIB Symbian's Socket
//
@@ -216,10 +221,10 @@ public:
static inline void Addr2pj(const TInetAddr & sym_addr,
pj_sockaddr_in &pj_addr)
{
- memset(&pj_addr, 0, sizeof(pj_sockaddr_in));
+ pj_bzero(&pj_addr, sizeof(pj_sockaddr_in));
pj_addr.sin_family = PJ_AF_INET;
- pj_addr.sin_addr.s_addr = sym_addr.Address();
- pj_addr.sin_port = (pj_uint16_t) sym_addr.Port();
+ pj_addr.sin_addr.s_addr = pj_htonl(sym_addr.Address());
+ pj_addr.sin_port = pj_htons((pj_uint16_t) sym_addr.Port());
}
@@ -228,8 +233,8 @@ public:
TInetAddr & sym_addr)
{
sym_addr.Init(KAfInet);
- sym_addr.SetAddress((TUint32)pj_addr.sin_addr.s_addr);
- sym_addr.SetPort(pj_addr.sin_port);
+ sym_addr.SetAddress((TUint32)pj_ntohl(pj_addr.sin_addr.s_addr));
+ sym_addr.SetPort(pj_ntohs(pj_addr.sin_port));
}
diff --git a/pjlib/src/pj/sock_symbian.cpp b/pjlib/src/pj/sock_symbian.cpp
index 5615dde7..8d2ab077 100644
--- a/pjlib/src/pj/sock_symbian.cpp
+++ b/pjlib/src/pj/sock_symbian.cpp
@@ -210,8 +210,11 @@ void CPjSocketReader::ReadData(TDes8 &aDesc, TInetAddr *addr)
*/
PJ_DEF(pj_uint16_t) pj_ntohs(pj_uint16_t netshort)
{
- /* There's no difference in host/network byte order in Symbian */
+#if PJ_IS_LITTLE_ENDIAN
+ return pj_swap16(netshort);
+#else
return netshort;
+#endif
}
/*
@@ -219,8 +222,11 @@ PJ_DEF(pj_uint16_t) pj_ntohs(pj_uint16_t netshort)
*/
PJ_DEF(pj_uint16_t) pj_htons(pj_uint16_t hostshort)
{
- /* There's no difference in host/network byte order in Symbian */
+#if PJ_IS_LITTLE_ENDIAN
+ return pj_swap16(hostshort);
+#else
return hostshort;
+#endif
}
/*
@@ -228,8 +234,11 @@ PJ_DEF(pj_uint16_t) pj_htons(pj_uint16_t hostshort)
*/
PJ_DEF(pj_uint32_t) pj_ntohl(pj_uint32_t netlong)
{
- /* There's no difference in host/network byte order in Symbian */
+#if PJ_IS_LITTLE_ENDIAN
+ return pj_swap32(netlong);
+#else
return netlong;
+#endif
}
/*
@@ -237,8 +246,11 @@ PJ_DEF(pj_uint32_t) pj_ntohl(pj_uint32_t netlong)
*/
PJ_DEF(pj_uint32_t) pj_htonl(pj_uint32_t hostlong)
{
- /* There's no difference in host/network byte order in Symbian */
- return hostlong;
+#if PJ_IS_LITTLE_ENDIAN
+ return pj_swap32(hostlong);
+#else
+ return netlong;
+#endif
}
/*
@@ -250,7 +262,8 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)
static TBuf<20> str16;
static char str8[20];
- TInetAddr temp_addr((TUint32)inaddr.s_addr, (TUint)0);
+ /* (Symbian IP address is in host byte order) */
+ TInetAddr temp_addr((TUint32)pj_ntohl(inaddr.s_addr), (TUint)0);
temp_addr.Output(str16);
return pj_unicode_to_ansi(str16.PtrZ(), str16.Length(),
@@ -294,8 +307,8 @@ PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)
TInetAddr addr;
addr.Init(KAfInet);
if (addr.Input(ip_addr) == KErrNone) {
- /* Success */
- inp->s_addr = addr.Address();
+ /* Success (Symbian IP address is in host byte order) */
+ inp->s_addr = pj_htonl(addr.Address());
return 1;
} else {
/* Error */
@@ -497,7 +510,7 @@ PJ_DEF(pj_status_t) pj_sock_bind_in( pj_sock_t sock,
PJ_CHECK_STACK();
- pj_memset(&addr, 0, sizeof(addr));
+ pj_bzero(&addr, sizeof(addr));
addr.sin_family = PJ_AF_INET;
addr.sin_addr.s_addr = pj_htonl(addr32);
addr.sin_port = pj_htons(port);
diff --git a/pjlib/src/pj/timer_symbian.cpp b/pjlib/src/pj/timer_symbian.cpp
new file mode 100644
index 00000000..398f7722
--- /dev/null
+++ b/pjlib/src/pj/timer_symbian.cpp
@@ -0,0 +1,272 @@
+/* $Id$ */
+/*
+ * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pj/timer.h>
+#include <pj/pool.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/lock.h>
+
+#include "os_symbian.h"
+
+
+#define DEFAULT_MAX_TIMED_OUT_PER_POLL (64)
+
+
+/**
+ * The implementation of timer heap.
+ */
+struct pj_timer_heap_t
+{
+ /** Maximum size of the heap. */
+ pj_size_t max_size;
+
+ /** Current size of the heap. */
+ pj_size_t cur_size;
+
+ /** Max timed out entries to process per poll. */
+ unsigned max_entries_per_poll;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ * Active object for each timer entry.
+ */
+class CPjTimerEntry : public CActive
+{
+public:
+ static CPjTimerEntry* NewL( pj_timer_heap_t *timer_heap,
+ pj_timer_entry *entry,
+ const pj_time_val *delay);
+
+ ~CPjTimerEntry();
+
+ virtual void RunL();
+ virtual void DoCancel();
+
+private:
+ pj_timer_heap_t *timer_heap_;
+ pj_timer_entry *entry_;
+ RTimer rtimer_;
+
+ CPjTimerEntry(pj_timer_heap_t *timer_heap, pj_timer_entry *entry);
+ void ConstructL(const pj_time_val *delay);
+};
+
+
+CPjTimerEntry::CPjTimerEntry(pj_timer_heap_t *timer_heap,
+ pj_timer_entry *entry)
+: CActive(PJ_SYMBIAN_TIMER_PRIORITY), timer_heap_(timer_heap), entry_(entry)
+{
+}
+
+CPjTimerEntry::~CPjTimerEntry()
+{
+ if (IsActive())
+ Cancel();
+ rtimer_.Close();
+}
+
+void CPjTimerEntry::ConstructL(const pj_time_val *delay)
+{
+ rtimer_.CreateLocal();
+ CActiveScheduler::Add(this);
+
+ rtimer_.After(iStatus, PJ_TIME_VAL_MSEC(*delay) * 1000);
+ SetActive();
+}
+
+CPjTimerEntry* CPjTimerEntry::NewL(pj_timer_heap_t *timer_heap,
+ pj_timer_entry *entry,
+ const pj_time_val *delay)
+{
+ CPjTimerEntry *self = new CPjTimerEntry(timer_heap, entry);
+ CleanupStack::PushL(self);
+ self->ConstructL(delay);
+ CleanupStack::Pop(self);
+
+ return self;
+}
+
+void CPjTimerEntry::RunL()
+{
+ --timer_heap_->cur_size;
+ entry_->_timer_id = NULL;
+ entry_->cb(timer_heap_, entry_);
+
+ // Finger's crossed!
+ delete this;
+}
+
+void CPjTimerEntry::DoCancel()
+{
+ rtimer_.Cancel();
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+
+/*
+ * Calculate memory size required to create a timer heap.
+ */
+PJ_DEF(pj_size_t) pj_timer_heap_mem_size(pj_size_t count)
+{
+ return /* size of the timer heap itself: */
+ sizeof(pj_timer_heap_t) +
+ /* size of each entry: */
+ (count+2) * (sizeof(pj_timer_entry*)+sizeof(pj_timer_id_t)) +
+ /* lock, pool etc: */
+ 132;
+}
+
+/*
+ * Create a new timer heap.
+ */
+PJ_DEF(pj_status_t) pj_timer_heap_create( pj_pool_t *pool,
+ pj_size_t size,
+ pj_timer_heap_t **p_heap)
+{
+ pj_timer_heap_t *ht;
+
+ PJ_ASSERT_RETURN(pool && p_heap, PJ_EINVAL);
+
+ *p_heap = NULL;
+
+ /* Allocate timer heap data structure from the pool */
+ ht = PJ_POOL_ALLOC_T(pool, pj_timer_heap_t);
+ if (!ht)
+ return PJ_ENOMEM;
+
+ /* Initialize timer heap sizes */
+ ht->max_size = size;
+ ht->cur_size = 0;
+ ht->max_entries_per_poll = DEFAULT_MAX_TIMED_OUT_PER_POLL;
+
+ *p_heap = ht;
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(void) pj_timer_heap_destroy( pj_timer_heap_t *ht )
+{
+ PJ_UNUSED_ARG(ht);
+}
+
+PJ_DEF(void) pj_timer_heap_set_lock( pj_timer_heap_t *ht,
+ pj_lock_t *lock,
+ pj_bool_t auto_del )
+{
+ PJ_UNUSED_ARG(ht);
+ if (auto_del)
+ pj_lock_destroy(lock);
+}
+
+
+PJ_DEF(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht,
+ unsigned count )
+{
+ unsigned old_count = ht->max_entries_per_poll;
+ ht->max_entries_per_poll = count;
+ return old_count;
+}
+
+PJ_DEF(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,
+ int id,
+ void *user_data,
+ pj_timer_heap_callback *cb )
+{
+ pj_assert(entry && cb);
+
+ entry->_timer_id = NULL;
+ entry->id = id;
+ entry->user_data = user_data;
+ entry->cb = cb;
+
+ return entry;
+}
+
+PJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht,
+ pj_timer_entry *entry,
+ const pj_time_val *delay)
+{
+ CPjTimerEntry *timerObj;
+
+ PJ_ASSERT_RETURN(ht && entry && delay, PJ_EINVAL);
+ PJ_ASSERT_RETURN(entry->cb != NULL, PJ_EINVAL);
+
+ /* Prevent same entry from being scheduled more than once */
+ PJ_ASSERT_RETURN(entry->_timer_id == NULL, PJ_EINVALIDOP);
+
+ timerObj = CPjTimerEntry::NewL(ht, entry, delay);
+ entry->_timer_id = (void*) timerObj;
+
+ ++ht->cur_size;
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(int) pj_timer_heap_cancel( pj_timer_heap_t *ht,
+ pj_timer_entry *entry)
+{
+ PJ_ASSERT_RETURN(ht && entry, PJ_EINVAL);
+
+ if (entry->_timer_id != NULL) {
+ CPjTimerEntry *timerObj = (CPjTimerEntry*) entry->_timer_id;
+ timerObj->Cancel();
+ delete timerObj;
+ entry->_timer_id = NULL;
+ --ht->cur_size;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+PJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht,
+ pj_time_val *next_delay )
+{
+ /* Polling is not necessary on Symbian, since all async activities
+ * are registered to active scheduler.
+ */
+ PJ_UNUSED_ARG(ht);
+ if (next_delay) {
+ next_delay->sec = 1;
+ next_delay->msec = 0;
+ }
+ return 0;
+}
+
+PJ_DEF(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht )
+{
+ PJ_ASSERT_RETURN(ht, 0);
+
+ return ht->cur_size;
+}
+
+PJ_DEF(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t * ht,
+ pj_time_val *timeval)
+{
+ /* We don't support this! */
+ PJ_UNUSED_ARG(ht);
+
+ timeval->sec = 1;
+ timeval->msec = 0;
+
+ return PJ_SUCCESS;
+}
+
diff --git a/pjsip-apps/src/symbian_ua/ua.cpp b/pjsip-apps/src/symbian_ua/ua.cpp
index 64482036..ee84eaf2 100644
--- a/pjsip-apps/src/symbian_ua/ua.cpp
+++ b/pjsip-apps/src/symbian_ua/ua.cpp
@@ -44,6 +44,11 @@
#define THIS_FILE "symbian_ua.cpp"
//
+// Destination URI (to make call, or to subscribe presence)
+//
+#define SIP_DST_URI "sip:192.168.0.70:5061"
+
+//
// Account
//
#define HAS_SIP_ACCOUNT 0 // 0 to disable registration
@@ -58,6 +63,12 @@
//#define SIP_PROXY "sip:192.168.0.1"
+//
+// Globals
+//
+static pjsua_acc_id g_acc_id = PJSUA_INVALID_ID;
+static pjsua_call_id g_call_id = PJSUA_INVALID_ID;
+static pjsua_buddy_id g_buddy_id = PJSUA_INVALID_ID;
/* Callback called by the library upon receiving incoming call */
@@ -69,12 +80,19 @@ static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
PJ_UNUSED_ARG(acc_id);
PJ_UNUSED_ARG(rdata);
+ if (g_call_id != PJSUA_INVALID_ID) {
+ pjsua_call_answer(call_id, PJSIP_SC_BUSY_HERE, NULL, NULL);
+ return;
+ }
+
pjsua_call_get_info(call_id, &ci);
PJ_LOG(3,(THIS_FILE, "Incoming call from %.*s!!",
(int)ci.remote_info.slen,
ci.remote_info.ptr));
+ g_call_id = call_id;
+
/* Automatically answer incoming calls with 200/OK */
pjsua_call_answer(call_id, 200, NULL, NULL);
}
@@ -87,6 +105,15 @@ static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
PJ_UNUSED_ARG(e);
pjsua_call_get_info(call_id, &ci);
+
+ if (ci.state == PJSIP_INV_STATE_DISCONNECTED) {
+ if (call_id == g_call_id)
+ g_call_id = PJSUA_INVALID_ID;
+ } else {
+ if (g_call_id == PJSUA_INVALID_ID)
+ g_call_id = call_id;
+ }
+
PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,
(int)ci.state_text.slen,
ci.state_text.ptr));
@@ -107,6 +134,92 @@ static void on_call_media_state(pjsua_call_id call_id)
}
+/* Handler on buddy state changed. */
+static void on_buddy_state(pjsua_buddy_id buddy_id)
+{
+ pjsua_buddy_info info;
+ pjsua_buddy_get_info(buddy_id, &info);
+
+ PJ_LOG(3,(THIS_FILE, "%.*s status is %.*s",
+ (int)info.uri.slen,
+ info.uri.ptr,
+ (int)info.status_text.slen,
+ info.status_text.ptr));
+}
+
+
+/* Incoming IM message (i.e. MESSAGE request)! */
+static void on_pager(pjsua_call_id call_id, const pj_str_t *from,
+ const pj_str_t *to, const pj_str_t *contact,
+ const pj_str_t *mime_type, const pj_str_t *text)
+{
+ /* Note: call index may be -1 */
+ PJ_UNUSED_ARG(call_id);
+ PJ_UNUSED_ARG(to);
+ PJ_UNUSED_ARG(contact);
+ PJ_UNUSED_ARG(mime_type);
+
+ PJ_LOG(3,(THIS_FILE,"MESSAGE from %.*s: %.*s",
+ (int)from->slen, from->ptr,
+ (int)text->slen, text->ptr));
+}
+
+
+/* Received typing indication */
+static void on_typing(pjsua_call_id call_id, const pj_str_t *from,
+ const pj_str_t *to, const pj_str_t *contact,
+ pj_bool_t is_typing)
+{
+ PJ_UNUSED_ARG(call_id);
+ PJ_UNUSED_ARG(to);
+ PJ_UNUSED_ARG(contact);
+
+ PJ_LOG(3,(THIS_FILE, "IM indication: %.*s %s",
+ (int)from->slen, from->ptr,
+ (is_typing?"is typing..":"has stopped typing")));
+}
+
+
+/* Call transfer request status. */
+static void on_call_transfer_status(pjsua_call_id call_id,
+ int status_code,
+ const pj_str_t *status_text,
+ pj_bool_t final,
+ pj_bool_t *p_cont)
+{
+ PJ_LOG(3,(THIS_FILE, "Call %d: transfer status=%d (%.*s) %s",
+ call_id, status_code,
+ (int)status_text->slen, status_text->ptr,
+ (final ? "[final]" : "")));
+
+ if (status_code/100 == 2) {
+ PJ_LOG(3,(THIS_FILE,
+ "Call %d: call transfered successfully, disconnecting call",
+ call_id));
+ pjsua_call_hangup(call_id, PJSIP_SC_GONE, NULL, NULL);
+ *p_cont = PJ_FALSE;
+ }
+}
+
+
+/* Notification that call is being replaced. */
+static void on_call_replaced(pjsua_call_id old_call_id,
+ pjsua_call_id new_call_id)
+{
+ pjsua_call_info old_ci, new_ci;
+
+ pjsua_call_get_info(old_call_id, &old_ci);
+ pjsua_call_get_info(new_call_id, &new_ci);
+
+ PJ_LOG(3,(THIS_FILE, "Call %d with %.*s is being replaced by "
+ "call %d with %.*s",
+ old_call_id,
+ (int)old_ci.remote_info.slen, old_ci.remote_info.ptr,
+ new_call_id,
+ (int)new_ci.remote_info.slen, new_ci.remote_info.ptr));
+}
+
+
/* Logging callback */
static void log_writer(int level, const char *buf, unsigned len)
{
@@ -125,9 +238,8 @@ static void log_writer(int level, const char *buf, unsigned len)
*
* url may contain URL to call.
*/
-static pj_status_t app_startup(char *url)
+static pj_status_t app_startup()
{
- pjsua_acc_id acc_id = 0;
pj_status_t status;
/* Redirect log before pjsua_init() */
@@ -140,15 +252,6 @@ static pj_status_t app_startup(char *url)
return status;
}
- /* If argument is specified, it's got to be a valid SIP URL */
- if (url) {
- status = pjsua_verify_sip_url(url);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Invalid URL", status);
- return status;
- }
- }
-
/* Init pjsua */
{
pjsua_config cfg;
@@ -161,6 +264,11 @@ static pj_status_t app_startup(char *url)
cfg.cb.on_incoming_call = &on_incoming_call;
cfg.cb.on_call_media_state = &on_call_media_state;
cfg.cb.on_call_state = &on_call_state;
+ cfg.cb.on_buddy_state = &on_buddy_state;
+ cfg.cb.on_pager = &on_pager;
+ cfg.cb.on_typing = &on_typing;
+ cfg.cb.on_call_transfer_status = &on_call_transfer_status;
+ cfg.cb.on_call_replaced = &on_call_replaced;
if (SIP_PROXY) {
cfg.outbound_proxy_cnt = 1;
@@ -199,7 +307,7 @@ static pj_status_t app_startup(char *url)
return status;
}
- pjsua_acc_add_local(tid, PJ_TRUE, &acc_id);
+ pjsua_acc_add_local(tid, PJ_TRUE, &g_acc_id);
}
/* Initialization is done, now start pjsua */
@@ -224,7 +332,7 @@ static pj_status_t app_startup(char *url)
cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
cfg.cred_info[0].data = pj_str(SIP_PASSWD);
- status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
+ status = pjsua_acc_add(&cfg, PJ_TRUE, &g_acc_id);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error adding account", status);
pjsua_destroy();
@@ -232,18 +340,15 @@ static pj_status_t app_startup(char *url)
}
}
- /* If URL is specified, make call to the URL. */
- if (url != NULL) {
- pj_str_t uri = pj_str(url);
- status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error making call", status);
- pjsua_destroy();
- return status;
- }
-
+ if (SIP_DST_URI) {
+ pjsua_buddy_config bcfg;
+
+ pjsua_buddy_config_default(&bcfg);
+ bcfg.uri = pj_str(SIP_DST_URI);
+ bcfg.subscribe = PJ_FALSE;
+
+ pjsua_buddy_add(&bcfg, &g_buddy_id);
}
-
return PJ_SUCCESS;
}
@@ -307,7 +412,13 @@ static void PrintMenu()
" d Dump states\n"
" D Dump all states (detail)\n"
" P Dump pool factory\n"
+ " m Make call\n"
+ " a Answer call\n"
" h Hangup all calls\n"
+ " s Subscribe to buddy presence\n"
+ " S Unsubscribe buddy presence\n"
+ " o Set account online\n"
+ " O Set account offline\n"
" q Quit\n"));
}
@@ -315,31 +426,60 @@ static void PrintMenu()
void ConsoleUI::RunL()
{
TKeyCode kc = con_->KeyCode();
-
+ pj_bool_t reschedule = PJ_TRUE;
+
switch (kc) {
case 'q':
asw_->AsyncStop();
+ reschedule = PJ_FALSE;
break;
case 'D':
case 'd':
pjsua_dump(kc == 'D');
- Run();
break;
case 'P':
pj_pool_factory_dump(&pjsua_var.cp.factory, PJ_TRUE);
break;
+ case 'm':
+ if (g_call_id != PJSUA_INVALID_ID) {
+ PJ_LOG(3,(THIS_FILE, "Another call is active"));
+ break;
+ }
+
+ if (pjsua_verify_sip_url(SIP_DST_URI) == PJ_SUCCESS) {
+ pj_str_t dst = pj_str(SIP_DST_URI);
+ pjsua_call_make_call(g_acc_id, &dst, 0, NULL,
+ NULL, &g_call_id);
+ } else {
+ PJ_LOG(3,(THIS_FILE, "Invalid SIP URI"));
+ }
+ break;
+ case 'a':
+ if (g_call_id != PJSUA_INVALID_ID)
+ pjsua_call_answer(g_call_id, 200, NULL, NULL);
+ break;
case 'h':
pjsua_call_hangup_all();
- Run();
+ break;
+ case 's':
+ case 'S':
+ if (g_buddy_id != PJSUA_INVALID_ID)
+ pjsua_buddy_subscribe_pres(g_buddy_id, kc=='s');
+ break;
+ case 'o':
+ case 'O':
+ pjsua_acc_set_online_status(g_acc_id, kc=='o');
break;
default:
PJ_LOG(3,(THIS_FILE, "Keycode '%c' (%d) is pressed",
kc, kc));
- Run();
break;
}
PrintMenu();
+
+ if (reschedule)
+ Run();
}
////////////////////////////////////////////////////////////////////////////
@@ -348,7 +488,7 @@ int ua_main()
pj_status_t status;
// Initialize pjsua
- status = app_startup("sip:192.168.0.77");
+ status = app_startup();
if (status != PJ_SUCCESS)
return status;
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 009f16a0..9f8188b3 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -141,12 +141,8 @@ static const pj_time_val td_timer_val = { PJSIP_TD_TIMEOUT/1000,
static const pj_time_val timeout_timer_val = { (64*PJSIP_T1_TIMEOUT)/1000,
(64*PJSIP_T1_TIMEOUT)%1000 };
-/* Internal timer IDs */
-enum Transaction_Timer_Id
-{
- TSX_TIMER_RETRANSMISSION,
- TSX_TIMER_TIMEOUT,
-};
+#define TIMER_INACTIVE 0
+#define TIMER_ACTIVE 1
/* Prototypes. */
@@ -910,12 +906,10 @@ static pj_status_t tsx_create( pjsip_module *tsx_user,
"tsx%p", tsx);
tsx->handle_200resp = 1;
- tsx->retransmit_timer.id = TSX_TIMER_RETRANSMISSION;
- tsx->retransmit_timer._timer_id = -1;
+ tsx->retransmit_timer.id = 0;
tsx->retransmit_timer.user_data = tsx;
tsx->retransmit_timer.cb = &tsx_timer_callback;
- tsx->timeout_timer.id = TSX_TIMER_TIMEOUT;
- tsx->timeout_timer._timer_id = -1;
+ tsx->timeout_timer.id = 0;
tsx->timeout_timer.user_data = tsx;
tsx->timeout_timer.cb = &tsx_timer_callback;
@@ -949,14 +943,14 @@ static pj_status_t tsx_destroy( pjsip_transaction *tsx )
tsx->last_tx = NULL;
}
/* Cancel timeout timer. */
- if (tsx->timeout_timer._timer_id != -1) {
+ if (tsx->timeout_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
- tsx->timeout_timer._timer_id = -1;
+ tsx->timeout_timer.id = 0;
}
/* Cancel retransmission timer. */
- if (tsx->retransmit_timer._timer_id != -1) {
+ if (tsx->retransmit_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
- tsx->retransmit_timer._timer_id = -1;
+ tsx->retransmit_timer.id = 0;
}
/* Clear some pending flags. */
@@ -1001,15 +995,13 @@ static void tsx_timer_callback( pj_timer_heap_t *theap, pj_timer_entry *entry)
PJ_UNUSED_ARG(theap);
+ entry->id = 0;
+
PJ_LOG(5,(tsx->obj_name, "%s timer event",
- (entry->id==TSX_TIMER_RETRANSMISSION ? "Retransmit":"Timeout")));
+ (entry==&tsx->retransmit_timer ? "Retransmit":"Timeout")));
- if (entry->id == TSX_TIMER_RETRANSMISSION) {
- PJSIP_EVENT_INIT_TIMER(event, &tsx->retransmit_timer);
- } else {
- PJSIP_EVENT_INIT_TIMER(event, &tsx->timeout_timer);
- }
+ PJSIP_EVENT_INIT_TIMER(event, entry);
/* Dispatch event to transaction. */
lock_tsx(tsx, &lck);
@@ -1081,11 +1073,12 @@ static void tsx_set_state( pjsip_transaction *tsx,
tsx->transport_flag |= TSX_HAS_PENDING_DESTROY;
} else {
/* Cancel timeout timer. */
- if (tsx->timeout_timer._timer_id != -1) {
+ if (tsx->timeout_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
- tsx->timeout_timer._timer_id = -1;
+ tsx->timeout_timer.id = 0;
}
+ tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
&timeout);
}
@@ -1821,6 +1814,7 @@ static void tsx_resched_retransmission( pjsip_transaction *tsx )
timeout.sec = msec_time / 1000;
timeout.msec = msec_time % 1000;
+ tsx->retransmit_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->retransmit_timer,
&timeout);
}
@@ -1912,6 +1906,7 @@ static pj_status_t tsx_on_state_null( pjsip_transaction *tsx,
/* Start Timer B (or called timer F for non-INVITE) for transaction
* timeout.
*/
+ tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
&timeout_timer_val);
@@ -1923,6 +1918,7 @@ static pj_status_t tsx_on_state_null( pjsip_transaction *tsx,
if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;
} else {
+ tsx->retransmit_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer(tsx->endpt, &tsx->retransmit_timer,
&t1_timer_val);
}
@@ -1963,9 +1959,9 @@ static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx,
{
/* Cancel retransmission timer. */
- if (tsx->retransmit_timer._timer_id != -1) {
+ if (tsx->retransmit_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
- tsx->retransmit_timer._timer_id = -1;
+ tsx->retransmit_timer.id = 0;
}
tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);
@@ -1996,23 +1992,23 @@ static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx,
* timer.
*/
if (code >= 200) {
- if (tsx->retransmit_timer._timer_id != -1) {
+ if (tsx->retransmit_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
- tsx->retransmit_timer._timer_id = -1;
+ tsx->retransmit_timer.id = 0;
}
- if (tsx->timeout_timer._timer_id != -1) {
+ if (tsx->timeout_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
- tsx->timeout_timer._timer_id = -1;
+ tsx->timeout_timer.id = 0;
}
} else {
/* Cancel retransmit timer (for non-INVITE transaction, the
* retransmit timer will be rescheduled at T2.
*/
- if (tsx->retransmit_timer._timer_id != -1) {
+ if (tsx->retransmit_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
- tsx->retransmit_timer._timer_id = -1;
+ tsx->retransmit_timer.id = 0;
}
/* For provisional response, only cancel retransmit when this
@@ -2028,6 +2024,7 @@ static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx,
} else {
if (!tsx->is_reliable) {
+ tsx->retransmit_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer(tsx->endpt,
&tsx->retransmit_timer,
&t2_timer_val);
@@ -2201,6 +2198,7 @@ static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,
if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;
} else {
+ tsx->retransmit_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer( tsx->endpt,
&tsx->retransmit_timer,
&t1_timer_val);
@@ -2239,6 +2237,7 @@ static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,
timeout.sec = timeout.msec = 0;
}
+ tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
&timeout);
@@ -2264,15 +2263,18 @@ static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,
*/
if (tsx->method.id == PJSIP_INVITE_METHOD) {
/* Start timer H for INVITE */
+ tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer(tsx->endpt,&tsx->timeout_timer,
&timeout_timer_val);
} else if (!tsx->is_reliable) {
/* Start timer J on 64*T1 seconds for non-INVITE */
+ tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer(tsx->endpt,&tsx->timeout_timer,
&timeout_timer_val);
} else {
/* Start timer J on zero seconds for non-INVITE */
pj_time_val zero_time = { 0, 0 };
+ tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer(tsx->endpt,&tsx->timeout_timer,
&zero_time);
}
@@ -2289,6 +2291,7 @@ static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,
if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;
} else {
+ tsx->retransmit_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer(tsx->endpt,
&tsx->retransmit_timer,
&t1_timer_val);
@@ -2426,13 +2429,14 @@ static pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx,
} else {
timeout.sec = timeout.msec = 0;
}
+ tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
&timeout);
/* Cancel retransmission timer */
- if (tsx->retransmit_timer._timer_id != -1) {
+ if (tsx->retransmit_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
- tsx->retransmit_timer._timer_id = -1;
+ tsx->retransmit_timer.id = 0;
}
/* Move state to Completed, inform TU. */
@@ -2493,6 +2497,7 @@ static pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx,
} else {
timeout.sec = timeout.msec = 0;
}
+ tsx->timeout->timer.id = TSX_TIMER_TIMEOUT;
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &timeout);
/* Inform TU.
@@ -2561,6 +2566,7 @@ static pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx,
} else {
timeout.sec = timeout.msec = 0;
}
+ tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &timeout);
} else {
@@ -2601,14 +2607,15 @@ static pj_status_t tsx_on_state_completed_uas( pjsip_transaction *tsx,
/* Process incoming ACK request. */
/* Cease retransmission. */
- if (tsx->retransmit_timer._timer_id != -1) {
+ if (tsx->retransmit_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
- tsx->retransmit_timer._timer_id = -1;
+ tsx->retransmit_timer.id = 0;
}
tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);
/* Start timer I in T4 interval (transaction termination). */
pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer );
+ tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
&t4_timer_val);
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 8a0e93e5..34691531 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -645,6 +645,9 @@ on_error:
/* Sleep with polling */
static void busy_sleep(unsigned msec)
{
+#if defined(PJ_SYMBIAN) && PJ_SYMBIAN != 0
+ pj_thread_sleep(msec);
+#else
pj_time_val timeout, now;
pj_gettimeofday(&timeout);
@@ -656,6 +659,7 @@ static void busy_sleep(unsigned msec)
;
pj_gettimeofday(&now);
} while (PJ_TIME_VAL_LT(now, timeout));
+#endif
}