* #27232: jni: added pjproject checkout as regular git content

We will remove it once the next release of pjsip (with Android support)
comes out and is merged into SFLphone.
diff --git a/jni/pjproject-android/.svn/pristine/21/21bfdda21634c7938f5895d9daa1566b4115313d.svn-base b/jni/pjproject-android/.svn/pristine/21/21bfdda21634c7938f5895d9daa1566b4115313d.svn-base
new file mode 100644
index 0000000..4b1d61b
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/21/21bfdda21634c7938f5895d9daa1566b4115313d.svn-base
@@ -0,0 +1,475 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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)
+
+// Maximum number of miliseconds that RTimer.At() supports
+#define MAX_RTIMER_INTERVAL		2147
+
+/* Absolute maximum number of timer entries */
+#ifndef PJ_SYMBIAN_TIMER_MAX_COUNT
+#  define PJ_SYMBIAN_TIMER_MAX_COUNT	65535
+#endif
+
+/* Get the number of free slots in the timer heap */
+#define FREECNT(th)	(th->max_size - th->cur_size)
+
+// Forward declaration
+class CPjTimerEntry;
+
+/**
+ * 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;
+
+    /** Array of timer entries. A scheduled timer will occupy one slot, and
+     *  the slot number will be saved in entry->_timer_id
+     */
+    CPjTimerEntry **entries;
+    
+    /** Array of free slot indexes in the "entries" array */
+    int *free_slots;
+};
+
+/**
+ * Active object for each timer entry.
+ */
+class CPjTimerEntry : public CActive 
+{
+public:
+    pj_timer_entry  *entry_;
+    
+    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_;
+    RTimer	     rtimer_;
+    pj_uint32_t	     interval_left_;
+    
+    CPjTimerEntry(pj_timer_heap_t *timer_heap, pj_timer_entry *entry);
+    void ConstructL(const pj_time_val *delay);
+    void Schedule();
+};
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * Implementation.
+ */
+
+/* Grow timer heap to the specified size */
+static pj_status_t realloc_timer_heap(pj_timer_heap_t *th, pj_size_t new_size)
+{
+    typedef CPjTimerEntry *entry_ptr;
+    CPjTimerEntry **entries = NULL;
+    int *free_slots = NULL;
+    unsigned i, j;
+ 
+    if (new_size > PJ_SYMBIAN_TIMER_MAX_COUNT) {
+	/* Just some sanity limit */
+	new_size = PJ_SYMBIAN_TIMER_MAX_COUNT;
+	if (new_size <= th->max_size) {
+	    /* We've grown large enough */
+	    pj_assert(!"Too many timer heap entries");
+	    return PJ_ETOOMANY;
+	}
+    }
+    
+    /* Allocate entries, move entries from the old array if there is one */
+    entries = new entry_ptr[new_size];
+    if (th->entries) {
+	pj_memcpy(entries, th->entries, th->max_size * sizeof(th->entries[0]));
+    }
+    /* Initialize the remaining new area */
+    pj_bzero(&entries[th->max_size], 
+	    (new_size - th->max_size) * sizeof(th->entries[0]));
+    
+    /* Allocate free slots array */
+    free_slots = new int[new_size];
+    if (th->free_slots) {
+	pj_memcpy(free_slots, th->free_slots, 
+		  FREECNT(th) * sizeof(th->free_slots[0]));
+    }
+    /* Initialize the remaining new area */
+    for (i=FREECNT(th), j=th->max_size; j<new_size; ++i, ++j) {
+	free_slots[i] = j;
+    }
+    for ( ; i<new_size; ++i) {
+	free_slots[i] = -1;
+    }
+    
+    /* Apply */
+    delete [] th->entries;
+    th->entries = entries;
+    th->max_size = new_size;
+    delete [] th->free_slots;
+    th->free_slots = free_slots;
+
+    return PJ_SUCCESS;
+}
+
+/* Allocate and register an entry to timer heap for newly scheduled entry */
+static pj_status_t add_entry(pj_timer_heap_t *th, CPjTimerEntry *entry)
+{
+    pj_status_t status;
+    int slot;
+    
+    /* Check that there's still capacity left in the timer heap */
+    if (FREECNT(th) < 1) {
+	// Grow the timer heap twice the capacity
+	status = realloc_timer_heap(th, th->max_size * 2);
+	if (status != PJ_SUCCESS)
+	    return status;
+    }
+    
+    /* Allocate one free slot. Use LIFO */
+    slot = th->free_slots[FREECNT(th)-1];
+    PJ_ASSERT_RETURN((slot >= 0) && (slot < (int)th->max_size) && 
+		     (th->entries[slot]==NULL), PJ_EBUG);
+    
+    th->free_slots[FREECNT(th)-1] = -1;
+    th->entries[slot] = entry;
+    entry->entry_->_timer_id = slot;
+    ++th->cur_size;
+    
+    return PJ_SUCCESS;
+}
+
+/* Free a slot when an entry's timer has elapsed or cancel */
+static pj_status_t remove_entry(pj_timer_heap_t *th, CPjTimerEntry *entry)
+{
+    int slot = entry->entry_->_timer_id;
+    
+    PJ_ASSERT_RETURN(slot >= 0 && slot < (int)th->max_size, PJ_EBUG);
+    PJ_ASSERT_RETURN(FREECNT(th) < th->max_size, PJ_EBUG);
+    PJ_ASSERT_RETURN(th->entries[slot]==entry, PJ_EBUG);
+    PJ_ASSERT_RETURN(th->free_slots[FREECNT(th)]==-1, PJ_EBUG);
+    
+    th->entries[slot] = NULL;
+    th->free_slots[FREECNT(th)] = slot;
+    entry->entry_->_timer_id = -1;
+    --th->cur_size;
+    
+    return PJ_SUCCESS;
+}
+
+
+CPjTimerEntry::CPjTimerEntry(pj_timer_heap_t *timer_heap,
+			     pj_timer_entry *entry)
+: CActive(PJ_SYMBIAN_TIMER_PRIORITY), entry_(entry), timer_heap_(timer_heap), 
+  interval_left_(0)
+{
+}
+
+CPjTimerEntry::~CPjTimerEntry() 
+{
+    Cancel();
+    rtimer_.Close();
+}
+
+void CPjTimerEntry::Schedule()
+{
+    pj_int32_t interval;
+    
+    if (interval_left_ > MAX_RTIMER_INTERVAL) {
+	interval = MAX_RTIMER_INTERVAL;
+    } else {
+	interval = interval_left_;
+    }
+    
+    interval_left_ -= interval;
+    rtimer_.After(iStatus, interval * 1000);
+    SetActive();
+}
+
+void CPjTimerEntry::ConstructL(const pj_time_val *delay) 
+{
+    rtimer_.CreateLocal();
+    CActiveScheduler::Add(this);
+    
+    interval_left_ = PJ_TIME_VAL_MSEC(*delay);
+    Schedule();
+}
+
+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() 
+{
+    if (interval_left_ > 0) {
+	Schedule();
+	return;
+    }
+    
+    remove_entry(timer_heap_, this);
+    entry_->cb(timer_heap_, entry_);
+    
+    // Finger's crossed!
+    delete this;
+}
+
+void CPjTimerEntry::DoCancel() 
+{
+    /* It's possible that _timer_id is -1, see schedule(). In this case,
+     * the entry has not been added to the timer heap, so don't remove
+     * it.
+     */
+    if (entry_ && entry_->_timer_id != -1)
+	remove_entry(timer_heap_, this);
+    
+    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(void*)+sizeof(int)) +
+           /* 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_status_t status;
+
+    PJ_ASSERT_RETURN(pool && p_heap, PJ_EINVAL);
+
+    *p_heap = NULL;
+
+    /* Allocate timer heap data structure from the pool */
+    ht = PJ_POOL_ZALLOC_T(pool, pj_timer_heap_t);
+    if (!ht)
+        return PJ_ENOMEM;
+
+    /* Allocate slots */
+    status = realloc_timer_heap(ht, size);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    *p_heap = ht;
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(void) pj_timer_heap_destroy( pj_timer_heap_t *ht )
+{
+    /* Cancel and delete pending active objects */
+    if (ht->entries) {
+	unsigned i;
+	for (i=0; i<ht->max_size; ++i) {
+	    if (ht->entries[i]) {
+		ht->entries[i]->entry_ = NULL;
+		ht->entries[i]->Cancel();
+		delete ht->entries[i];
+		ht->entries[i] = NULL;
+	    }
+	}
+    }
+    
+    delete [] ht->entries;
+    delete [] ht->free_slots;
+    
+    ht->entries = NULL;
+    ht->free_slots = NULL;
+}
+
+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 )
+{
+    /* Not applicable */
+    PJ_UNUSED_ARG(count);
+    return ht->max_size;
+}
+
+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 = -1;
+    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_status_t status;
+    
+    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 < 1, PJ_EINVALIDOP);
+
+    entry->_timer_id = -1;
+    
+    timerObj = CPjTimerEntry::NewL(ht, entry, delay);
+    status = add_entry(ht, timerObj);
+    if (status != PJ_SUCCESS) {
+	timerObj->Cancel();
+	delete timerObj;
+	return status;
+    }
+    
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_timer_heap_schedule_w_grp_lock(pj_timer_heap_t *ht,
+                                                      pj_timer_entry *entry,
+                                                      const pj_time_val *delay,
+                                                      int id_val,
+                                                      pj_grp_lock_t *grp_lock)
+{
+    pj_status_t status;
+	    
+    PJ_UNUSED_ARG(grp_lock);
+
+    status = pj_timer_heap_schedule(ht, entry, delay);
+    
+    if (status == PJ_SUCCESS)
+    	entry->id = id_val;
+    
+    return status;
+}
+
+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 >= 0 && entry->_timer_id < (int)ht->max_size) {
+    	CPjTimerEntry *timerObj = ht->entries[entry->_timer_id];
+    	if (timerObj) {
+    	    timerObj->Cancel();
+    	    delete timerObj;
+    	    return 1;
+    	} else {
+    	    return 0;
+    	}
+    } else {
+    	return 0;
+    }
+}
+
+PJ_DEF(int) pj_timer_heap_cancel_if_active(pj_timer_heap_t *ht,
+                                           pj_timer_entry *entry,
+                                           int id_val)
+{
+    int count = pj_timer_heap_cancel(ht, entry);
+    if (count == 1)
+    	entry->id = id_val;
+    
+    return count;
+}
+
+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;
+}
+