diff options
-rw-r--r-- | build.symbian/pjlib.mmp | 6 | ||||
-rw-r--r-- | build.symbian/pjlib_util.mmp | 1 | ||||
-rw-r--r-- | build.symbian/pjproject.cww | 222 | ||||
-rw-r--r-- | build.symbian/symbian_ua.mmp | 4 | ||||
-rw-r--r-- | pjlib/include/pj/compat/cc_armcc.h | 50 | ||||
-rw-r--r-- | pjlib/include/pj/compat/cc_gcce.h | 51 | ||||
-rw-r--r-- | pjlib/include/pj/config.h | 4 | ||||
-rw-r--r-- | pjlib/include/pj/timer.h | 4 | ||||
-rw-r--r-- | pjlib/src/pj/guid_simple.c | 4 | ||||
-rw-r--r-- | pjlib/src/pj/ioqueue_symbian.cpp | 46 | ||||
-rw-r--r-- | pjlib/src/pj/os_core_symbian.cpp | 8 | ||||
-rw-r--r-- | pjlib/src/pj/os_symbian.h | 15 | ||||
-rw-r--r-- | pjlib/src/pj/sock_symbian.cpp | 31 | ||||
-rw-r--r-- | pjlib/src/pj/timer_symbian.cpp | 272 | ||||
-rw-r--r-- | pjsip-apps/src/symbian_ua/ua.cpp | 198 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transaction.c | 75 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 4 |
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 } |