summaryrefslogtreecommitdiff
path: root/pjlib/src
diff options
context:
space:
mode:
Diffstat (limited to 'pjlib/src')
-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
6 files changed, 317 insertions, 59 deletions
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;
+}
+