* #39226: Switch back to pjsip rev 4710

Rev 4716 introduces errors when building for android (miltiple definitions)
diff --git a/jni/pjproject-android/.svn/pristine/58/589aa995228ea2f8a74ef2e18e89b8c431f88e31.svn-base b/jni/pjproject-android/.svn/pristine/58/589aa995228ea2f8a74ef2e18e89b8c431f88e31.svn-base
new file mode 100644
index 0000000..35b0504
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/58/589aa995228ea2f8a74ef2e18e89b8c431f88e31.svn-base
@@ -0,0 +1,560 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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 <pjmedia.h>
+#include <pjmedia/converter.h>
+#include <pjmedia-codec.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+/**
+ * \page page_pjmedia_samples_aviplay_c Samples: Playing AVI File to
+ * Video and Sound Devices
+ *
+ * This is a very simple example to use the @ref PJMEDIA_FILE_PLAY,
+ * @ref PJMED_SND_PORT, and @ref PJMEDIA_VID_PORT. In this example, we
+ * open the file, video, and sound devices, then connect the file to both
+ * video and sound devices to play the contents of the file.
+ *
+ *
+ * This file is pjsip-apps/src/samples/aviplay.c
+ *
+ * \includelineno aviplay.c
+ */
+
+
+/*
+ * aviplay.c
+ *
+ * PURPOSE:
+ *  Play a AVI file to video and sound devices.
+ *
+ * USAGE:
+ *  aviplay FILE.AVI
+ */
+
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+
+
+/* For logging purpose. */
+#define THIS_FILE   "aviplay.c"
+
+static const char *desc = 
+" FILE		    						    \n"
+"		    						    \n"
+"  aviplay.c	    						    \n"
+"		    						    \n"
+" PURPOSE	    						    \n"
+"		    						    \n"
+"  Demonstrate how to play a AVI file.				    \n"
+"		    						    \n"
+" USAGE		    						    \n"
+"		    						    \n"
+"  aviplay FILE.AVI						    \n";
+
+struct codec_fmt {
+    pj_uint32_t         pjmedia_id;
+    const char         *codec_id;
+    /* Do we need to convert the decoded frame? */
+    pj_bool_t           need_conversion;
+    /* If conversion is needed, dst_fmt indicates the destination format */
+    pjmedia_format_id   dst_fmt;
+} codec_fmts[] = {{PJMEDIA_FORMAT_MJPEG, "mjpeg",
+                   PJ_TRUE , PJMEDIA_FORMAT_I420},
+                  {PJMEDIA_FORMAT_H263 , "h263" ,
+                   PJ_FALSE, 0},
+                  {PJMEDIA_FORMAT_MPEG4, "mp4v"}, 
+                  {PJMEDIA_FORMAT_H264 , "h264"}
+                 };
+
+typedef struct avi_port_t
+{
+    pjmedia_vid_port   *vid_port;
+    pjmedia_snd_port   *snd_port;
+    pj_bool_t           is_running;
+    pj_bool_t           is_quitting;
+} avi_port_t;
+
+typedef struct codec_port_data_t
+{
+    pjmedia_vid_codec   *codec;
+    pjmedia_port        *src_port;
+    pj_uint8_t          *enc_buf;
+    pj_size_t            enc_buf_size;
+    
+    pjmedia_converter   *conv;
+} codec_port_data_t;
+
+static pj_status_t avi_event_cb(pjmedia_event *event,
+                                void *user_data)
+{
+    avi_port_t *ap = (avi_port_t *)user_data;
+    
+    switch (event->type) {
+    case PJMEDIA_EVENT_WND_CLOSED:
+        ap->is_quitting = PJ_TRUE;
+        break;
+    case PJMEDIA_EVENT_MOUSE_BTN_DOWN:
+        if (ap->is_running) {
+            pjmedia_vid_port_stop(ap->vid_port);
+            if (ap->snd_port)
+                pjmedia_aud_stream_stop(
+                    pjmedia_snd_port_get_snd_stream(ap->snd_port));
+        } else {
+            pjmedia_vid_port_start(ap->vid_port);
+            if (ap->snd_port)
+                pjmedia_aud_stream_start(
+                    pjmedia_snd_port_get_snd_stream(ap->snd_port));
+        }
+        ap->is_running = !ap->is_running;
+        break;
+    default:
+        return PJ_SUCCESS;
+    }
+    
+    /* We handled the event on our own, so return non-PJ_SUCCESS here */
+    return -1;
+}
+
+static pj_status_t codec_get_frame(pjmedia_port *port,
+			           pjmedia_frame *frame)
+{
+    codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata;
+    pjmedia_vid_codec *codec = port_data->codec;
+    pjmedia_frame enc_frame;
+    pj_status_t status;
+    
+    enc_frame.buf = port_data->enc_buf;
+    enc_frame.size = port_data->enc_buf_size;
+    
+    if (port_data->conv) {
+        pj_size_t frame_size = frame->size;
+	
+        status = pjmedia_port_get_frame(port_data->src_port, frame);
+        if (status != PJ_SUCCESS) goto on_error;
+	
+        status = pjmedia_vid_codec_decode(codec, 1, frame,
+                                          (unsigned)frame->size, &enc_frame);
+        if (status != PJ_SUCCESS) goto on_error;
+	
+        frame->size = frame_size;
+        status = pjmedia_converter_convert(port_data->conv, &enc_frame, frame);
+        if (status != PJ_SUCCESS) goto on_error;
+	
+        return PJ_SUCCESS;
+    }
+    
+    status = pjmedia_port_get_frame(port_data->src_port, &enc_frame);
+    if (status != PJ_SUCCESS) goto on_error;
+    
+    status = pjmedia_vid_codec_decode(codec, 1, &enc_frame,
+                                      (unsigned)frame->size, frame);
+    if (status != PJ_SUCCESS) goto on_error;
+    
+    return PJ_SUCCESS;
+    
+on_error:
+    pj_perror(3, THIS_FILE, status, "codec_get_frame() error");
+    return status;
+}
+
+static int aviplay(pj_pool_t *pool, const char *fname)
+{
+    pjmedia_vid_port *renderer=NULL;
+    pjmedia_vid_port_param param;
+    const pjmedia_video_format_info *vfi;
+    pjmedia_video_format_detail *vfd;
+    pjmedia_snd_port *snd_port = NULL;
+    pj_status_t status;
+    int rc = 0;
+    pjmedia_avi_streams *avi_streams;
+    pjmedia_avi_stream *vid_stream, *aud_stream;
+    pjmedia_port *vid_port = NULL, *aud_port = NULL;
+    pjmedia_vid_codec *codec=NULL;
+    avi_port_t avi_port;
+    
+    pj_bzero(&avi_port, sizeof(avi_port));
+    
+    status = pjmedia_avi_player_create_streams(pool, fname, 0, &avi_streams);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(2,("", status, "    Error playing %s", fname));
+	rc = 210; goto on_return;
+    }
+    
+    vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
+                                                         0,
+                                                         PJMEDIA_TYPE_VIDEO);
+    vid_port = pjmedia_avi_stream_get_port(vid_stream);
+    
+    if (vid_port) {
+        pjmedia_vid_port_param_default(&param);
+	
+        status = pjmedia_vid_dev_default_param(pool,
+                                               PJMEDIA_VID_DEFAULT_RENDER_DEV,
+                                               &param.vidparam);
+        if (status != PJ_SUCCESS) {
+    	    rc = 220; goto on_return;
+        }
+	
+        /* Create renderer, set it to active  */
+        param.active = PJ_TRUE;
+        param.vidparam.dir = PJMEDIA_DIR_RENDER;
+        vfd = pjmedia_format_get_video_format_detail(&vid_port->info.fmt,
+                                                     PJ_TRUE);
+        pjmedia_format_init_video(&param.vidparam.fmt, 
+                                  vid_port->info.fmt.id,
+                                  vfd->size.w, vfd->size.h,
+                                  vfd->fps.num, vfd->fps.denum);
+	
+        vfi = pjmedia_get_video_format_info(
+                  pjmedia_video_format_mgr_instance(),
+                  vid_port->info.fmt.id);
+        /* Check whether the frame is encoded */
+        if (!vfi || vfi->bpp == 0) {
+            /* Yes, prepare codec */
+            pj_str_t codec_id_st;
+            unsigned info_cnt = 1, i, k;
+            const pjmedia_vid_codec_info *codec_info;
+            pj_str_t port_name = {"codec", 5};
+            pj_uint8_t *enc_buf = NULL;
+            pj_size_t enc_buf_size = 0;
+            pjmedia_vid_dev_info rdr_info;
+            pjmedia_port codec_port;
+            codec_port_data_t codec_port_data;
+            pjmedia_vid_codec_param codec_param;
+            struct codec_fmt *codecp = NULL;
+	    
+            /* Lookup codec */
+            for (i = 0; i < sizeof(codec_fmts)/sizeof(codec_fmts[0]); i++) {
+                if (vid_port->info.fmt.id == codec_fmts[i].pjmedia_id) {
+                    codecp = &codec_fmts[i];
+                    break;
+                }
+            }
+            if (!codecp) {
+                rc = 242; goto on_return;
+            }
+            pj_cstr(&codec_id_st, codecp->codec_id);
+            status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
+                                                             &codec_id_st, 
+                                                             &info_cnt, 
+                                                             &codec_info,
+                                                             NULL);
+            if (status != PJ_SUCCESS) {
+                rc = 245; goto on_return;
+            }
+            status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
+                                                             &codec_param);
+            if (status != PJ_SUCCESS) {
+                rc = 246; goto on_return;
+            }
+	    
+            pjmedia_format_copy(&codec_param.enc_fmt, &param.vidparam.fmt);
+
+            pjmedia_vid_dev_get_info(param.vidparam.rend_id, &rdr_info);
+            for (i=0; i<codec_info->dec_fmt_id_cnt; ++i) {
+                for (k=0; k<rdr_info.fmt_cnt; ++k) {
+                    if (codec_info->dec_fmt_id[i]==(int)rdr_info.fmt[k].id)
+                    {
+                        param.vidparam.fmt.id = codec_info->dec_fmt_id[i];
+                        i = codec_info->dec_fmt_id_cnt;
+                        break;
+                    }
+                }
+            }
+	    
+            /* Open codec */
+            status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
+                                                       &codec);
+            if (status != PJ_SUCCESS) {
+                rc = 250; goto on_return;
+            }
+	    
+            status = pjmedia_vid_codec_init(codec, pool);
+            if (status != PJ_SUCCESS) {
+                rc = 251; goto on_return;
+            }
+	    
+            pjmedia_format_copy(&codec_param.dec_fmt, &param.vidparam.fmt);
+            codec_param.dir = PJMEDIA_DIR_DECODING;
+            codec_param.packing = PJMEDIA_VID_PACKING_WHOLE;
+            status = pjmedia_vid_codec_open(codec, &codec_param);
+            if (status != PJ_SUCCESS) {
+                rc = 252; goto on_return;
+            }
+	    
+            /* Alloc encoding buffer */
+            enc_buf_size =  codec_param.dec_fmt.det.vid.size.w *
+	    codec_param.dec_fmt.det.vid.size.h * 4
+	    + 16; /*< padding, just in case */
+            enc_buf = pj_pool_alloc(pool,enc_buf_size);
+	    
+            /* Init codec port */
+            pj_bzero(&codec_port, sizeof(codec_port));
+            status = pjmedia_port_info_init2(&codec_port.info, &port_name,
+                                             0x1234,
+                                             PJMEDIA_DIR_ENCODING, 
+                                             &codec_param.dec_fmt);
+            if (status != PJ_SUCCESS) {
+                rc = 260; goto on_return;
+            }
+            pj_bzero(&codec_port_data, sizeof(codec_port_data));
+            codec_port_data.codec = codec;
+            codec_port_data.src_port = vid_port;
+            codec_port_data.enc_buf = enc_buf;
+            codec_port_data.enc_buf_size = enc_buf_size;
+	    
+            codec_port.get_frame = &codec_get_frame;
+            codec_port.port_data.pdata = &codec_port_data;
+	    
+            /* Check whether we need to convert the decoded frame */
+            if (codecp->need_conversion) {
+                pjmedia_conversion_param conv_param;
+		
+                pjmedia_format_copy(&conv_param.src, &param.vidparam.fmt);
+                pjmedia_format_copy(&conv_param.dst, &param.vidparam.fmt);
+                conv_param.dst.id = codecp->dst_fmt;
+                param.vidparam.fmt.id = conv_param.dst.id;
+		
+                status = pjmedia_converter_create(NULL, pool, &conv_param,
+                                                  &codec_port_data.conv);
+                if (status != PJ_SUCCESS) {
+                    rc = 270; goto on_return;
+                }
+            }
+	    
+            status = pjmedia_vid_port_create(pool, &param, &renderer);
+            if (status != PJ_SUCCESS) {
+                rc = 230; goto on_return;
+            }
+	    
+            status = pjmedia_vid_port_connect(renderer, &codec_port,
+                                              PJ_FALSE);
+        } else {
+            status = pjmedia_vid_port_create(pool, &param, &renderer);
+            if (status != PJ_SUCCESS) {
+                rc = 230; goto on_return;
+            }
+	    
+            /* Connect avi port to renderer */
+            status = pjmedia_vid_port_connect(renderer, vid_port,
+                                              PJ_FALSE);
+        }
+	
+        if (status != PJ_SUCCESS) {
+            rc = 240; goto on_return;
+        }
+    }
+    
+    aud_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
+                                                         0,
+                                                         PJMEDIA_TYPE_AUDIO);
+    aud_port = pjmedia_avi_stream_get_port(aud_stream);
+    
+    if (aud_port) {
+        /* Create sound player port. */
+        status = pjmedia_snd_port_create_player( 
+		 pool,				    /* pool		    */
+		 -1,				    /* use default dev.	    */
+		 PJMEDIA_PIA_SRATE(&aud_port->info),/* clock rate.	    */
+		 PJMEDIA_PIA_CCNT(&aud_port->info), /* # of channels.	    */
+		 PJMEDIA_PIA_SPF(&aud_port->info),  /* samples per frame.   */
+		 PJMEDIA_PIA_BITS(&aud_port->info), /* bits per sample.	    */
+		 0,				    /* options		    */
+		 &snd_port			    /* returned port	    */
+		 );
+        if (status != PJ_SUCCESS) {
+            rc = 310; goto on_return;
+        }
+	
+        /* Connect file port to the sound player.
+         * Stream playing will commence immediately.
+         */
+        status = pjmedia_snd_port_connect(snd_port, aud_port);
+        if (status != PJ_SUCCESS) {
+            rc = 330; goto on_return;
+        }
+    }
+    
+    if (vid_port) {
+        pjmedia_vid_dev_cb cb;
+	
+        pj_bzero(&cb, sizeof(cb));
+        avi_port.snd_port = snd_port;
+        avi_port.vid_port = renderer;
+        avi_port.is_running = PJ_TRUE;
+        pjmedia_vid_port_set_cb(renderer, &cb, &avi_port);
+
+        /* subscribe events */
+        pjmedia_event_subscribe(NULL, &avi_event_cb, &avi_port,
+                                renderer);
+
+        if (snd_port) {
+            /* Synchronize video rendering and audio playback */
+            pjmedia_vid_port_set_clock_src(
+                renderer,
+                pjmedia_snd_port_get_clock_src(
+                    snd_port, PJMEDIA_DIR_PLAYBACK));
+        }
+                                              
+	
+        /* Start video streaming.. */
+        status = pjmedia_vid_port_start(renderer);
+        if (status != PJ_SUCCESS) {
+            rc = 270; goto on_return;
+        }
+    }
+    
+    while (!avi_port.is_quitting) {
+        pj_thread_sleep(100);
+    }
+
+on_return:
+    if (snd_port) {
+        pjmedia_snd_port_disconnect(snd_port);
+        /* Without this sleep, Windows/DirectSound will repeteadly
+         * play the last frame during destroy.
+         */
+        pj_thread_sleep(100);
+        pjmedia_snd_port_destroy(snd_port);
+    }
+    if (renderer) {
+        pjmedia_event_unsubscribe(NULL, &avi_event_cb, &avi_port,
+                                  renderer);
+        pjmedia_vid_port_destroy(renderer);
+    }
+    if (aud_port)
+        pjmedia_port_destroy(aud_port);
+    if (vid_port)
+        pjmedia_port_destroy(vid_port);
+    if (codec) {
+        pjmedia_vid_codec_close(codec);
+        pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
+    }
+    
+    return rc;
+}
+
+
+static int main_func(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pj_pool_t *pool;
+    int rc = 0;
+    pj_status_t status = PJ_SUCCESS;
+    
+    if (argc != 2) {
+    	puts("Error: filename required");
+	puts(desc);
+	return 1;
+    }
+
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "AVI",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
+    pjmedia_converter_mgr_create(pool, NULL);
+    pjmedia_event_mgr_create(pool, 0, NULL);
+    pjmedia_vid_codec_mgr_create(pool, NULL);
+    
+    status = pjmedia_vid_dev_subsys_init(&cp.factory);
+    if (status != PJ_SUCCESS)
+        goto on_return;
+    
+    status = pjmedia_aud_subsys_init(&cp.factory);
+    if (status != PJ_SUCCESS) {
+        goto on_return;
+    }
+    
+#if PJMEDIA_HAS_FFMPEG_VID_CODEC
+    status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory);
+    if (status != PJ_SUCCESS)
+	goto on_return;    
+#endif
+
+    rc = aviplay(pool, argv[1]);
+    
+    /* 
+     * File should be playing and looping now 
+     */
+
+    /* Without this sleep, Windows/DirectSound will repeteadly
+     * play the last frame during destroy.
+     */
+    pj_thread_sleep(100);
+
+on_return:    
+#if PJMEDIA_HAS_FFMPEG_VID_CODEC
+    pjmedia_codec_ffmpeg_vid_deinit();
+#endif
+    pjmedia_aud_subsys_shutdown();
+    pjmedia_vid_dev_subsys_shutdown();
+    
+    pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance());
+    pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance());
+    pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance());
+    pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance());    
+    
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+    /* Done. */
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    return pj_run_app(&main_func, argc, argv, 0);
+}
+
+#else
+
+int main(int argc, char *argv[])
+{
+    PJ_UNUSED_ARG(argc);
+    PJ_UNUSED_ARG(argv);
+    puts("Error: this sample requires video capability (PJMEDIA_HAS_VIDEO == 1)");
+    return -1;
+}
+
+#endif /* PJMEDIA_HAS_VIDEO */
diff --git a/jni/pjproject-android/.svn/pristine/58/58a487951c315a502b28459aef17c6bc1a767415.svn-base b/jni/pjproject-android/.svn/pristine/58/58a487951c315a502b28459aef17c6bc1a767415.svn-base
new file mode 100644
index 0000000..058aa4c
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/58/58a487951c315a502b28459aef17c6bc1a767415.svn-base
@@ -0,0 +1,430 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/short_term.c,v 1.2 1994/05/10 20:18:47 jutta Exp $ */
+
+#include "config.h"
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/*
+ *  SHORT TERM ANALYSIS FILTERING SECTION
+ */
+
+/* 4.2.8 */
+
+static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp),
+	word 	* LARc,		/* coded log area ratio	[0..7] 	IN	*/
+	word	* LARpp)	/* out: decoded ..			*/
+{
+	register word	temp1 /* , temp2 */;
+	register long	ltmp;	/* for GSM_ADD */
+
+	/*  This procedure requires for efficient implementation
+	 *  two tables.
+ 	 *
+	 *  INVA[1..8] = integer( (32768 * 8) / real_A[1..8])
+	 *  MIC[1..8]  = minimum value of the LARc[1..8]
+	 */
+
+	/*  Compute the LARpp[1..8]
+	 */
+
+	/* 	for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {
+	 *
+	 *		temp1  = GSM_ADD( *LARc, *MIC ) << 10;
+	 *		temp2  = *B << 1;
+	 *		temp1  = GSM_SUB( temp1, temp2 );
+	 *
+	 *		assert(*INVA != MIN_WORD);
+	 *
+	 *		temp1  = GSM_MULT_R( *INVA, temp1 );
+	 *		*LARpp = GSM_ADD( temp1, temp1 );
+	 *	}
+	 */
+
+#undef	STEP
+#define	STEP( B, MIC, INVA )	\
+		temp1    = GSM_ADD( *LARc++, MIC ) << 10;	\
+		temp1    = GSM_SUB( temp1, B << 1 );		\
+		temp1    = GSM_MULT_R( INVA, temp1 );		\
+		*LARpp++ = GSM_ADD( temp1, temp1 );
+
+	STEP(      0,  -32,  13107 );
+	STEP(      0,  -32,  13107 );
+	STEP(   2048,  -16,  13107 );
+	STEP(  -2560,  -16,  13107 );
+
+	STEP(     94,   -8,  19223 );
+	STEP(  -1792,   -8,  17476 );
+	STEP(   -341,   -4,  31454 );
+	STEP(  -1144,   -4,  29708 );
+
+	/* NOTE: the addition of *MIC is used to restore
+	 * 	 the sign of *LARc.
+	 */
+}
+
+/* 4.2.9 */
+/* Computation of the quantized reflection coefficients 
+ */
+
+/* 4.2.9.1  Interpolation of the LARpp[1..8] to get the LARp[1..8]
+ */
+
+/*
+ *  Within each frame of 160 analyzed speech samples the short term
+ *  analysis and synthesis filters operate with four different sets of
+ *  coefficients, derived from the previous set of decoded LARs(LARpp(j-1))
+ *  and the actual set of decoded LARs (LARpp(j))
+ *
+ * (Initial value: LARpp(j-1)[1..8] = 0.)
+ */
+
+static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp),
+	register word * LARpp_j_1,
+	register word * LARpp_j,
+	register word * LARp)
+{
+	register int 	i;
+	register longword ltmp;
+
+	for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) {
+		*LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
+		*LARp = GSM_ADD( *LARp,  SASR( *LARpp_j_1, 1));
+	}
+}
+
+static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp),
+	register word * LARpp_j_1,
+	register word * LARpp_j,
+	register word * LARp)
+{
+	register int i;
+	register longword ltmp;
+	for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+		*LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 ));
+	}
+}
+
+static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp),
+	register word * LARpp_j_1,
+	register word * LARpp_j,
+	register word * LARp)
+{
+	register int i;
+	register longword ltmp;
+
+	for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+		*LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
+		*LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 ));
+	}
+}
+
+
+static void Coefficients_40_159 P2((LARpp_j, LARp),
+	register word * LARpp_j,
+	register word * LARp)
+{
+	register int i;
+
+	for (i = 1; i <= 8; i++, LARp++, LARpp_j++)
+		*LARp = *LARpp_j;
+}
+
+/* 4.2.9.2 */
+
+static void LARp_to_rp P1((LARp),
+	register word * LARp)	/* [0..7] IN/OUT  */
+/*
+ *  The input of this procedure is the interpolated LARp[0..7] array.
+ *  The reflection coefficients, rp[i], are used in the analysis
+ *  filter and in the synthesis filter.
+ */
+{
+	register int 		i;
+	register word		temp;
+	register longword	ltmp;
+
+	for (i = 1; i <= 8; i++, LARp++) {
+
+		/* temp = GSM_ABS( *LARp );
+	         *
+		 * if (temp < 11059) temp <<= 1;
+		 * else if (temp < 20070) temp += 11059;
+		 * else temp = GSM_ADD( temp >> 2, 26112 );
+		 *
+		 * *LARp = *LARp < 0 ? -temp : temp;
+		 */
+
+		if (*LARp < 0) {
+			temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp);
+			*LARp = - ((temp < 11059) ? temp << 1
+				: ((temp < 20070) ? temp + 11059
+				:  GSM_ADD( temp >> 2, 26112 )));
+		} else {
+			temp  = *LARp;
+			*LARp =    (temp < 11059) ? temp << 1
+				: ((temp < 20070) ? temp + 11059
+				:  GSM_ADD( temp >> 2, 26112 ));
+		}
+	}
+}
+
+
+/* 4.2.10 */
+static void Short_term_analysis_filtering P4((S,rp,k_n,s),
+	struct gsm_state * S,
+	register word	* rp,	/* [0..7]	IN	*/
+	register int 	k_n, 	/*   k_end - k_start	*/
+	register word	* s	/* [0..n-1]	IN/OUT	*/
+)
+/*
+ *  This procedure computes the short term residual signal d[..] to be fed
+ *  to the RPE-LTP loop from the s[..] signal and from the local rp[..]
+ *  array (quantized reflection coefficients).  As the call of this
+ *  procedure can be done in many ways (see the interpolation of the LAR
+ *  coefficient), it is assumed that the computation begins with index
+ *  k_start (for arrays d[..] and s[..]) and stops with index k_end
+ *  (k_start and k_end are defined in 4.2.9.1).  This procedure also
+ *  needs to keep the array u[0..7] in memory for each call.
+ */
+{
+	register word		* u = S->u;
+	register int		i;
+	register word		di, zzz, ui, sav, rpi;
+	register longword 	ltmp;
+
+	for (; k_n--; s++) {
+
+		di = sav = *s;
+
+		for (i = 0; i < 8; i++) {		/* YYY */
+
+			ui    = u[i];
+			rpi   = rp[i];
+			u[i]  = sav;
+
+			zzz   = GSM_MULT_R(rpi, di);
+			sav   = GSM_ADD(   ui,  zzz);
+
+			zzz   = GSM_MULT_R(rpi, ui);
+			di    = GSM_ADD(   di,  zzz );
+		}
+
+		*s = di;
+	}
+}
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s),
+	struct gsm_state * S,
+	register word	* rp,	/* [0..7]	IN	*/
+	register int 	k_n, 	/*   k_end - k_start	*/
+	register word	* s	/* [0..n-1]	IN/OUT	*/
+)
+{
+	register word		* u = S->u;
+	register int		i;
+
+	float 	  uf[8],
+		 rpf[8];
+
+	register float scalef = 3.0517578125e-5;
+	register float		sav, di, temp;
+
+	for (i = 0; i < 8; ++i) {
+		uf[i]  = u[i];
+		rpf[i] = rp[i] * scalef;
+	}
+	for (; k_n--; s++) {
+		sav = di = *s;
+		for (i = 0; i < 8; ++i) {
+			register float rpfi = rpf[i];
+			register float ufi  = uf[i];
+
+			uf[i] = sav;
+			temp  = rpfi * di + ufi;
+			di   += rpfi * ufi;
+			sav   = temp;
+		}
+		*s = di;
+	}
+	for (i = 0; i < 8; ++i) u[i] = uf[i];
+}
+#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
+
+static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
+	struct gsm_state * S,
+	register word	* rrp,	/* [0..7]	IN	*/
+	register int	k,	/* k_end - k_start	*/
+	register word	* wt,	/* [0..k-1]	IN	*/
+	register word	* sr	/* [0..k-1]	OUT	*/
+)
+{
+	register word		* v = S->v;
+	register int		i;
+	register word		sri, tmp1, tmp2;
+	register longword	ltmp;	/* for GSM_ADD  & GSM_SUB */
+
+	while (k--) {
+		sri = *wt++;
+		for (i = 8; i--;) {
+
+			/* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );
+			 */
+			tmp1 = rrp[i];
+			tmp2 = v[i];
+			tmp2 =  ( tmp1 == MIN_WORD && tmp2 == MIN_WORD
+				? MAX_WORD
+				: 0x0FFFF & (( (longword)tmp1 * (longword)tmp2
+					     + 16384) >> 15)) ;
+
+			sri  = GSM_SUB( sri, tmp2 );
+
+			/* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
+			 */
+			tmp1  = ( tmp1 == MIN_WORD && sri == MIN_WORD
+				? MAX_WORD
+				: 0x0FFFF & (( (longword)tmp1 * (longword)sri
+					     + 16384) >> 15)) ;
+
+			v[i+1] = GSM_ADD( v[i], tmp1);
+		}
+		*sr++ = v[0] = sri;
+	}
+}
+
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+
+static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
+	struct gsm_state * S,
+	register word	* rrp,	/* [0..7]	IN	*/
+	register int	k,	/* k_end - k_start	*/
+	register word	* wt,	/* [0..k-1]	IN	*/
+	register word	* sr	/* [0..k-1]	OUT	*/
+)
+{
+	register word		* v = S->v;
+	register int		i;
+
+	float va[9], rrpa[8];
+	register float scalef = 3.0517578125e-5, temp;
+
+	for (i = 0; i < 8; ++i) {
+		va[i]   = v[i];
+		rrpa[i] = (float)rrp[i] * scalef;
+	}
+	while (k--) {
+		register float sri = *wt++;
+		for (i = 8; i--;) {
+			sri -= rrpa[i] * va[i];
+			if     (sri < -32768.) sri = -32768.;
+			else if (sri > 32767.) sri =  32767.;
+
+			temp = va[i] + rrpa[i] * sri;
+			if     (temp < -32768.) temp = -32768.;
+			else if (temp > 32767.) temp =  32767.;
+			va[i+1] = temp;
+		}
+		*sr++ = va[0] = sri;
+	}
+	for (i = 0; i < 9; ++i) v[i] = va[i];
+}
+
+#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */
+
+void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s),
+
+	struct gsm_state * S,
+
+	word	* LARc,		/* coded log area ratio [0..7]  IN	*/
+	word	* s		/* signal [0..159]		IN/OUT	*/
+)
+{
+	word		* LARpp_j	= S->LARpp[ S->j      ];
+	word		* LARpp_j_1	= S->LARpp[ S->j ^= 1 ];
+
+	word		LARp[8];
+
+#undef	FILTER
+#if 	defined(FAST) && defined(USE_FLOAT_MUL)
+# 	define	FILTER 	(* (S->fast			\
+			   ? Fast_Short_term_analysis_filtering	\
+		    	   : Short_term_analysis_filtering	))
+
+#else
+# 	define	FILTER	Short_term_analysis_filtering
+#endif
+
+	Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
+
+	Coefficients_0_12(  LARpp_j_1, LARpp_j, LARp );
+	LARp_to_rp( LARp );
+	FILTER( S, LARp, 13, s);
+
+	Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
+	LARp_to_rp( LARp );
+	FILTER( S, LARp, 14, s + 13);
+
+	Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
+	LARp_to_rp( LARp );
+	FILTER( S, LARp, 13, s + 27);
+
+	Coefficients_40_159( LARpp_j, LARp);
+	LARp_to_rp( LARp );
+	FILTER( S, LARp, 120, s + 40);
+}
+
+void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s),
+	struct gsm_state * S,
+
+	word	* LARcr,	/* received log area ratios [0..7] IN  */
+	word	* wt,		/* received d [0..159]		   IN  */
+
+	word	* s		/* signal   s [0..159]		  OUT  */
+)
+{
+	word		* LARpp_j	= S->LARpp[ S->j     ];
+	word		* LARpp_j_1	= S->LARpp[ S->j ^=1 ];
+
+	word		LARp[8];
+
+#undef	FILTER
+#if 	defined(FAST) && defined(USE_FLOAT_MUL)
+
+# 	define	FILTER 	(* (S->fast			\
+			   ? Fast_Short_term_synthesis_filtering	\
+		    	   : Short_term_synthesis_filtering	))
+#else
+#	define	FILTER	Short_term_synthesis_filtering
+#endif
+
+	Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
+
+	Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
+	LARp_to_rp( LARp );
+	FILTER( S, LARp, 13, wt, s );
+
+	Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
+	LARp_to_rp( LARp );
+	FILTER( S, LARp, 14, wt + 13, s + 13 );
+
+	Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
+	LARp_to_rp( LARp );
+	FILTER( S, LARp, 13, wt + 27, s + 27 );
+
+	Coefficients_40_159( LARpp_j, LARp );
+	LARp_to_rp( LARp );
+	FILTER(S, LARp, 120, wt + 40, s + 40);
+}
diff --git a/jni/pjproject-android/.svn/pristine/58/58afbb90d70bd80feafe6496b63bd2a0fb94304f.svn-base b/jni/pjproject-android/.svn/pristine/58/58afbb90d70bd80feafe6496b63bd2a0fb94304f.svn-base
new file mode 100644
index 0000000..1e435bc
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/58/58afbb90d70bd80feafe6496b63bd2a0fb94304f.svn-base
@@ -0,0 +1,141 @@
+/* Copyright (C) 2002 Jean-Marc Valin */
+/**
+   @file ltp.h
+   @brief Long-Term Prediction functions
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <speex/speex_bits.h>
+#include "arch.h"
+
+/** LTP parameters. */
+typedef struct {
+   const signed char *gain_cdbk;
+   int     gain_bits;
+   int     pitch_bits;
+} ltp_params;
+
+#ifdef FIXED_POINT
+#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -SHR16(g[0],1)) + (g[2]>0 ? g[2] : -SHR16(g[2],1)))
+#else
+#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -.5*g[0]) + (g[2]>0 ? g[2] : -.5*g[2]))
+#endif
+
+spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len);
+void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack);
+
+void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack);
+
+
+/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
+int pitch_search_3tap(
+spx_word16_t target[],                 /* Target vector */
+spx_word16_t *sw,
+spx_coef_t ak[],                     /* LPCs for this subframe */
+spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
+spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
+spx_sig_t exc[],                    /* Overlapping codebook */
+const void *par,
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+SpeexBits *bits,
+char *stack,
+spx_word16_t *exc2,
+spx_word16_t *r,
+int   complexity,
+int   cdbk_offset,
+int plc_tuning,
+spx_word32_t *cumul_gain
+);
+
+/*Unquantize adaptive codebook and update pitch contribution*/
+void pitch_unquant_3tap(
+spx_word16_t exc[],             /* Input excitation */
+spx_word32_t exc_out[],         /* Output excitation */
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,        /* Voicing (pitch) coefficient */
+const void *par,
+int   nsf,                      /* Number of samples in subframe */
+int *pitch_val,
+spx_word16_t *gain_val,
+SpeexBits *bits,
+char *stack,
+int lost,
+int subframe_offset,
+spx_word16_t last_pitch_gain,
+int cdbk_offset
+);
+
+/** Forced pitch delay and gain */
+int forced_pitch_quant(
+spx_word16_t target[],                 /* Target vector */
+spx_word16_t *sw,
+spx_coef_t ak[],                     /* LPCs for this subframe */
+spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
+spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
+spx_sig_t exc[],                    /* Excitation */
+const void *par,
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+SpeexBits *bits,
+char *stack,
+spx_word16_t *exc2,
+spx_word16_t *r,
+int complexity,
+int cdbk_offset,
+int plc_tuning,
+spx_word32_t *cumul_gain
+);
+
+/** Unquantize forced pitch delay and gain */
+void forced_pitch_unquant(
+spx_word16_t exc[],             /* Input excitation */
+spx_word32_t exc_out[],         /* Output excitation */
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,        /* Voicing (pitch) coefficient */
+const void *par,
+int   nsf,                      /* Number of samples in subframe */
+int *pitch_val,
+spx_word16_t *gain_val,
+SpeexBits *bits,
+char *stack,
+int lost,
+int subframe_offset,
+spx_word16_t last_pitch_gain,
+int cdbk_offset
+);
diff --git a/jni/pjproject-android/.svn/pristine/58/58bc4f37aeb2e5e77d11d258d881cb22464b8991.svn-base b/jni/pjproject-android/.svn/pristine/58/58bc4f37aeb2e5e77d11d258d881cb22464b8991.svn-base
new file mode 100644
index 0000000..d40c171
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/58/58bc4f37aeb2e5e77d11d258d881cb22464b8991.svn-base
@@ -0,0 +1,387 @@
+/* $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 "test.h"
+
+#if INCLUDE_IOQUEUE_UNREG_TEST
+/*
+ * This tests the thread safety of ioqueue unregistration operation.
+ */
+
+#include <pj/errno.h>
+#include <pj/ioqueue.h>
+#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/pool.h>
+#include <pj/sock.h>
+#include <pj/compat/socket.h>
+#include <pj/string.h>
+
+
+#define THIS_FILE   "ioq_unreg.c"
+
+
+enum test_method
+{
+    UNREGISTER_IN_APP,
+    UNREGISTER_IN_CALLBACK,
+};
+
+static int thread_quitting;
+static enum test_method test_method;
+static pj_time_val time_to_unregister;
+
+struct sock_data
+{
+    pj_sock_t		 sock;
+    pj_sock_t		 csock;
+    pj_pool_t		*pool;
+    pj_ioqueue_key_t	*key;
+    pj_mutex_t		*mutex;
+    pj_ioqueue_op_key_t	*op_key;
+    char		*buffer;
+    pj_size_t		 bufsize;
+    pj_bool_t		 unregistered;
+    pj_ssize_t		 received;
+} sock_data;
+
+static void on_read_complete(pj_ioqueue_key_t *key, 
+                             pj_ioqueue_op_key_t *op_key, 
+                             pj_ssize_t bytes_read)
+{
+    pj_ssize_t size;
+    char *sendbuf = "Hello world";
+    pj_status_t status;
+
+    if (sock_data.unregistered)
+	return;
+
+    pj_mutex_lock(sock_data.mutex);
+
+    if (sock_data.unregistered) {
+	pj_mutex_unlock(sock_data.mutex);
+	return;
+    }
+
+    if (bytes_read < 0) {
+	if (-bytes_read != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL))
+	    app_perror("ioqueue reported recv error", (pj_status_t)-bytes_read);
+    } else {
+	sock_data.received += bytes_read;
+    }
+
+    if (test_method == UNREGISTER_IN_CALLBACK) {
+	pj_time_val now;
+
+	pj_gettimeofday(&now);
+	if (PJ_TIME_VAL_GTE(now, time_to_unregister)) { 
+	    sock_data.unregistered = 1;
+	    pj_ioqueue_unregister(key);
+	    pj_mutex_unlock(sock_data.mutex);
+	    return;
+	}
+    }
+ 
+    do { 
+	size = sock_data.bufsize;
+	status = pj_ioqueue_recv(key, op_key, sock_data.buffer, &size, 0);
+	if (status != PJ_EPENDING && status != PJ_SUCCESS)
+	    app_perror("recv() error", status);
+
+    } while (status == PJ_SUCCESS);
+
+    pj_mutex_unlock(sock_data.mutex);
+
+    size = pj_ansi_strlen(sendbuf);
+    status = pj_sock_send(sock_data.csock, sendbuf, &size, 0);
+    if (status != PJ_SUCCESS)
+	app_perror("send() error", status);
+
+    size = pj_ansi_strlen(sendbuf);
+    status = pj_sock_send(sock_data.csock, sendbuf, &size, 0);
+    if (status != PJ_SUCCESS)
+	app_perror("send() error", status);
+
+} 
+
+static int worker_thread(void *arg)
+{
+    pj_ioqueue_t *ioqueue = (pj_ioqueue_t*) arg;
+
+    while (!thread_quitting) {
+	pj_time_val timeout = { 0, 20 };
+	pj_ioqueue_poll(ioqueue, &timeout);
+    }
+
+    return 0;
+}
+
+/*
+ * Perform unregistration test.
+ *
+ * This will create ioqueue and register a server socket. Depending
+ * on the test method, either the callback or the main thread will
+ * unregister and destroy the server socket after some period of time.
+ */
+static int perform_unreg_test(pj_ioqueue_t *ioqueue,
+			      pj_pool_t *test_pool,
+			      const char *title, 
+			      pj_bool_t other_socket)
+{
+    enum { WORKER_CNT = 1, MSEC = 500, QUIT_MSEC = 500 };
+    int i;
+    pj_thread_t *thread[WORKER_CNT];
+    struct sock_data osd;
+    pj_ioqueue_callback callback;
+    pj_time_val end_time;
+    pj_status_t status;
+
+
+    /* Sometimes its important to have other sockets registered to
+     * the ioqueue, because when no sockets are registered, the ioqueue
+     * will return from the poll early.
+     */
+    if (other_socket) {
+	status = app_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, 56127, &osd.sock);
+	if (status != PJ_SUCCESS) {
+	    app_perror("Error creating other socket", status);
+	    return -12;
+	}
+
+	pj_bzero(&callback, sizeof(callback));
+	status = pj_ioqueue_register_sock(test_pool, ioqueue, osd.sock,
+					  NULL, &callback, &osd.key);
+	if (status != PJ_SUCCESS) {
+	    app_perror("Error registering other socket", status);
+	    return -13;
+	}
+
+    } else {
+	osd.key = NULL;
+	osd.sock = PJ_INVALID_SOCKET;
+    }
+
+    /* Init both time duration of testing */
+    thread_quitting = 0;
+    pj_gettimeofday(&time_to_unregister);
+    time_to_unregister.msec += MSEC;
+    pj_time_val_normalize(&time_to_unregister);
+
+    end_time = time_to_unregister;
+    end_time.msec += QUIT_MSEC;
+    pj_time_val_normalize(&end_time);
+
+    
+    /* Create polling thread */
+    for (i=0; i<WORKER_CNT; ++i) {
+	status = pj_thread_create(test_pool, "unregtest", &worker_thread,
+				   ioqueue, 0, 0, &thread[i]);
+	if (status != PJ_SUCCESS) {
+	    app_perror("Error creating thread", status);
+	    return -20;
+	}
+    }
+
+    /* Create pair of client/server sockets */
+    status = app_socketpair(pj_AF_INET(), pj_SOCK_DGRAM(), 0, 
+			    &sock_data.sock, &sock_data.csock);
+    if (status != PJ_SUCCESS) {
+	app_perror("app_socketpair error", status);
+	return -30;
+    }
+
+
+    /* Initialize test data */
+    sock_data.pool = pj_pool_create(mem, "sd", 1000, 1000, NULL);
+    sock_data.buffer = (char*) pj_pool_alloc(sock_data.pool, 128);
+    sock_data.bufsize = 128;
+    sock_data.op_key = (pj_ioqueue_op_key_t*) 
+    		       pj_pool_alloc(sock_data.pool, 
+				     sizeof(*sock_data.op_key));
+    sock_data.received = 0;
+    sock_data.unregistered = 0;
+
+    pj_ioqueue_op_key_init(sock_data.op_key, sizeof(*sock_data.op_key));
+
+    status = pj_mutex_create_simple(sock_data.pool, "sd", &sock_data.mutex);
+    if (status != PJ_SUCCESS) {
+	app_perror("create_mutex() error", status);
+	return -35;
+    }
+
+    /* Register socket to ioqueue */
+    pj_bzero(&callback, sizeof(callback));
+    callback.on_read_complete = &on_read_complete;
+    status = pj_ioqueue_register_sock(sock_data.pool, ioqueue, sock_data.sock,
+				      NULL, &callback, &sock_data.key);
+    if (status != PJ_SUCCESS) {
+	app_perror("pj_ioqueue_register error", status);
+	return -40;
+    }
+
+    /* Bootstrap the first send/receive */
+    on_read_complete(sock_data.key, sock_data.op_key, 0);
+
+    /* Loop until test time ends */
+    for (;;) {
+	pj_time_val now, timeout;
+	int n;
+
+	pj_gettimeofday(&now);
+
+	if (test_method == UNREGISTER_IN_APP && 
+	    PJ_TIME_VAL_GTE(now, time_to_unregister) &&
+	    !sock_data.unregistered) 
+	{
+	    sock_data.unregistered = 1;
+	    /* Wait (as much as possible) for callback to complete */
+	    pj_mutex_lock(sock_data.mutex);
+	    pj_mutex_unlock(sock_data.mutex);
+	    pj_ioqueue_unregister(sock_data.key);
+	}
+
+	if (PJ_TIME_VAL_GT(now, end_time) && sock_data.unregistered)
+	    break;
+
+	timeout.sec = 0; timeout.msec = 10;
+	n = pj_ioqueue_poll(ioqueue, &timeout);
+	if (n < 0) {
+	    app_perror("pj_ioqueue_poll error", -n);
+	    pj_thread_sleep(1);
+	}
+    }
+
+    thread_quitting = 1;
+
+    for (i=0; i<WORKER_CNT; ++i) {
+	pj_thread_join(thread[i]);
+	pj_thread_destroy(thread[i]);
+    }
+
+    /* Destroy data */
+    pj_mutex_destroy(sock_data.mutex);
+    pj_pool_release(sock_data.pool);
+    sock_data.pool = NULL;
+
+    if (other_socket) {
+	pj_ioqueue_unregister(osd.key);
+    }
+
+    pj_sock_close(sock_data.csock);
+
+    PJ_LOG(3,(THIS_FILE, "....%s: done (%d KB/s)",
+	      title, sock_data.received * 1000 / MSEC / 1000));
+    return 0;
+}
+
+static int udp_ioqueue_unreg_test_imp(pj_bool_t allow_concur)
+{
+    enum { LOOP = 10 };
+    int i, rc;
+    char title[30];
+    pj_ioqueue_t *ioqueue;
+    pj_pool_t *test_pool;
+	
+    PJ_LOG(3,(THIS_FILE, "..testing with concurency=%d", allow_concur));
+
+    test_method = UNREGISTER_IN_APP;
+
+    test_pool = pj_pool_create(mem, "unregtest", 4000, 4000, NULL);
+
+    rc = pj_ioqueue_create(test_pool, 16, &ioqueue);
+    if (rc != PJ_SUCCESS) {
+	app_perror("Error creating ioqueue", rc);
+	return -10;
+    }
+
+    rc = pj_ioqueue_set_default_concurrency(ioqueue, allow_concur);
+    if (rc != PJ_SUCCESS) {
+	app_perror("Error in pj_ioqueue_set_default_concurrency()", rc);
+	return -12;
+    }
+
+    PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 0/3, unregister in app (%s)", 
+	       pj_ioqueue_name()));
+    for (i=0; i<LOOP; ++i) {
+	pj_ansi_sprintf(title, "repeat %d/%d", i, LOOP);
+	rc = perform_unreg_test(ioqueue, test_pool, title, 0);
+	if (rc != 0)
+	    return rc;
+    }
+
+
+    PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 1/3, unregister in app (%s)",
+	       pj_ioqueue_name()));
+    for (i=0; i<LOOP; ++i) {
+	pj_ansi_sprintf(title, "repeat %d/%d", i, LOOP);
+	rc = perform_unreg_test(ioqueue, test_pool, title, 1);
+	if (rc != 0)
+	    return rc;
+    }
+
+    test_method = UNREGISTER_IN_CALLBACK;
+
+    PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 2/3, unregister in cb (%s)", 
+	       pj_ioqueue_name()));
+    for (i=0; i<LOOP; ++i) {
+	pj_ansi_sprintf(title, "repeat %d/%d", i, LOOP);
+	rc = perform_unreg_test(ioqueue, test_pool, title, 0);
+	if (rc != 0)
+	    return rc;
+    }
+
+
+    PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 3/3, unregister in cb (%s)", 
+	       pj_ioqueue_name()));
+    for (i=0; i<LOOP; ++i) {
+	pj_ansi_sprintf(title, "repeat %d/%d", i, LOOP);
+	rc = perform_unreg_test(ioqueue, test_pool, title, 1);
+	if (rc != 0)
+	    return rc;
+    }
+
+    pj_ioqueue_destroy(ioqueue);
+    pj_pool_release(test_pool);
+
+    return 0;
+}
+
+int udp_ioqueue_unreg_test(void)
+{
+    int rc;
+
+    rc = udp_ioqueue_unreg_test_imp(PJ_TRUE);
+    if (rc != 0)
+    	return rc;
+
+    rc = udp_ioqueue_unreg_test_imp(PJ_FALSE);
+    if (rc != 0)
+	return rc;
+
+    return 0;
+}
+
+#else
+/* To prevent warning about "translation unit is empty"
+ * when this test is disabled. 
+ */
+int dummy_uiq_unreg;
+#endif	/* INCLUDE_IOQUEUE_UNREG_TEST */
+
+
diff --git a/jni/pjproject-android/.svn/pristine/58/58c4f387dcaa3197bcb89b1f22debb519da66a26.svn-base b/jni/pjproject-android/.svn/pristine/58/58c4f387dcaa3197bcb89b1f22debb519da66a26.svn-base
new file mode 100644
index 0000000..d1f66b8
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/58/58c4f387dcaa3197bcb89b1f22debb519da66a26.svn-base
@@ -0,0 +1,1311 @@
+/* $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 <pjsip/sip_endpoint.h>
+#include <pjsip/sip_transaction.h>
+#include <pjsip/sip_private.h>
+#include <pjsip/sip_event.h>
+#include <pjsip/sip_resolve.h>
+#include <pjsip/sip_module.h>
+#include <pjsip/sip_util.h>
+#include <pjsip/sip_errno.h>
+#include <pj/except.h>
+#include <pj/log.h>
+#include <pj/string.h>
+#include <pj/os.h>
+#include <pj/pool.h>
+#include <pj/hash.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/lock.h>
+
+#define PJSIP_EX_NO_MEMORY  pj_NO_MEMORY_EXCEPTION()
+#define THIS_FILE	    "sip_endpoint.c"
+
+#define MAX_METHODS   32
+
+
+/* List of SIP endpoint exit callback. */
+typedef struct exit_cb
+{
+    PJ_DECL_LIST_MEMBER		    (struct exit_cb);
+    pjsip_endpt_exit_callback	    func;
+} exit_cb;
+
+
+/**
+ * The SIP endpoint.
+ */
+struct pjsip_endpoint
+{
+    /** Pool to allocate memory for the endpoint. */
+    pj_pool_t		*pool;
+
+    /** Mutex for the pool, hash table, and event list/queue. */
+    pj_mutex_t		*mutex;
+
+    /** Pool factory. */
+    pj_pool_factory	*pf;
+
+    /** Name. */
+    pj_str_t		 name;
+
+    /** Timer heap. */
+    pj_timer_heap_t	*timer_heap;
+
+    /** Transport manager. */
+    pjsip_tpmgr		*transport_mgr;
+
+    /** Ioqueue. */
+    pj_ioqueue_t	*ioqueue;
+
+    /** Last ioqueue err */
+    pj_status_t		 ioq_last_err;
+
+    /** DNS Resolver. */
+    pjsip_resolver_t	*resolver;
+
+    /** Modules lock. */
+    pj_rwmutex_t	*mod_mutex;
+
+    /** Modules. */
+    pjsip_module        *modules[PJSIP_MAX_MODULE];
+
+    /** Module list, sorted by priority. */
+    pjsip_module	 module_list;
+
+    /** Capability header list. */
+    pjsip_hdr		 cap_hdr;
+
+    /** Additional request headers. */
+    pjsip_hdr		 req_hdr;
+
+    /** List of exit callback. */
+    exit_cb		 exit_cb_list;
+};
+
+
+#if defined(PJSIP_SAFE_MODULE) && PJSIP_SAFE_MODULE!=0
+#   define LOCK_MODULE_ACCESS(ept)	pj_rwmutex_lock_read(ept->mod_mutex)
+#   define UNLOCK_MODULE_ACCESS(ept)	pj_rwmutex_unlock_read(ept->mod_mutex)
+#else
+#   define LOCK_MODULE_ACCESS(endpt)
+#   define UNLOCK_MODULE_ACCESS(endpt)
+#endif
+
+
+
+/*
+ * Prototypes.
+ */
+static void endpt_on_rx_msg( pjsip_endpoint*, 
+			     pj_status_t, pjsip_rx_data*);
+static pj_status_t endpt_on_tx_msg( pjsip_endpoint *endpt,
+				    pjsip_tx_data *tdata );
+static pj_status_t unload_module(pjsip_endpoint *endpt,
+				 pjsip_module *mod);
+
+/* Defined in sip_parser.c */
+void init_sip_parser(void);
+void deinit_sip_parser(void);
+
+/* Defined in sip_tel_uri.c */
+pj_status_t pjsip_tel_uri_subsys_init(void);
+
+
+/*
+ * This is the global handler for memory allocation failure, for pools that
+ * are created by the endpoint (by default, all pools ARE allocated by 
+ * endpoint). The error is handled by throwing exception, and hopefully,
+ * the exception will be handled by the application (or this library).
+ */
+static void pool_callback( pj_pool_t *pool, pj_size_t size )
+{
+    PJ_UNUSED_ARG(pool);
+    PJ_UNUSED_ARG(size);
+
+    PJ_THROW(PJSIP_EX_NO_MEMORY);
+}
+
+
+/* Compare module name, used for searching module based on name. */
+static int cmp_mod_name(void *name, const void *mod)
+{
+    return pj_stricmp((const pj_str_t*)name, &((pjsip_module*)mod)->name);
+}
+
+/*
+ * Register new module to the endpoint.
+ * The endpoint will then call the load and start function in the module to 
+ * properly initialize the module, and assign a unique module ID for the 
+ * module.
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_register_module( pjsip_endpoint *endpt,
+						 pjsip_module *mod )
+{
+    pj_status_t status = PJ_SUCCESS;
+    pjsip_module *m;
+    unsigned i;
+
+    pj_rwmutex_lock_write(endpt->mod_mutex);
+
+    /* Make sure that this module has not been registered. */
+    PJ_ASSERT_ON_FAIL(	pj_list_find_node(&endpt->module_list, mod) == NULL,
+			{status = PJ_EEXISTS; goto on_return;});
+
+    /* Make sure that no module with the same name has been registered. */
+    PJ_ASSERT_ON_FAIL(	pj_list_search(&endpt->module_list, &mod->name, 
+				       &cmp_mod_name)==NULL,
+			{status = PJ_EEXISTS; goto on_return; });
+
+    /* Find unused ID for this module. */
+    for (i=0; i<PJ_ARRAY_SIZE(endpt->modules); ++i) {
+	if (endpt->modules[i] == NULL)
+	    break;
+    }
+    if (i == PJ_ARRAY_SIZE(endpt->modules)) {
+	pj_assert(!"Too many modules registered!");
+	status = PJ_ETOOMANY;
+	goto on_return;
+    }
+
+    /* Assign the ID. */
+    mod->id = i;
+
+    /* Try to load the module. */
+    if (mod->load) {
+	status = (*mod->load)(endpt);
+	if (status != PJ_SUCCESS)
+	    goto on_return;
+    }
+
+    /* Try to start the module. */
+    if (mod->start) {
+	status = (*mod->start)();
+	if (status != PJ_SUCCESS)
+	    goto on_return;
+    }
+
+    /* Save the module. */
+    endpt->modules[i] = mod;
+
+    /* Put in the module list, sorted by priority. */
+    m = endpt->module_list.next;
+    while (m != &endpt->module_list) {
+	if (m->priority > mod->priority)
+	    break;
+	m = m->next;
+    }
+    pj_list_insert_before(m, mod);
+
+    /* Done. */
+
+    PJ_LOG(4,(THIS_FILE, "Module \"%.*s\" registered", 
+	      (int)mod->name.slen, mod->name.ptr));
+
+on_return:
+    pj_rwmutex_unlock_write(endpt->mod_mutex);
+    return status;
+}
+
+/*
+ * Unregister a module from the endpoint.
+ * The endpoint will then call the stop and unload function in the module to 
+ * properly shutdown the module.
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_unregister_module( pjsip_endpoint *endpt,
+						   pjsip_module *mod )
+{
+    pj_status_t status;
+
+    pj_rwmutex_lock_write(endpt->mod_mutex);
+
+    /* Make sure the module exists in the list. */
+    PJ_ASSERT_ON_FAIL(	pj_list_find_node(&endpt->module_list, mod) == mod,
+			{status = PJ_ENOTFOUND;goto on_return;} );
+
+    /* Make sure the module exists in the array. */
+    PJ_ASSERT_ON_FAIL(	mod->id>=0 && 
+			mod->id<(int)PJ_ARRAY_SIZE(endpt->modules) &&
+			endpt->modules[mod->id] == mod,
+			{status = PJ_ENOTFOUND; goto on_return;});
+
+    /* Try to stop the module. */
+    if (mod->stop) {
+	status = (*mod->stop)();
+	if (status != PJ_SUCCESS) goto on_return;
+    }
+
+    /* Unload module */
+    status = unload_module(endpt, mod);
+
+on_return:
+    pj_rwmutex_unlock_write(endpt->mod_mutex);
+
+    if (status != PJ_SUCCESS) {
+	char errmsg[PJ_ERR_MSG_SIZE];
+
+	pj_strerror(status, errmsg, sizeof(errmsg));
+	PJ_LOG(3,(THIS_FILE, "Module \"%.*s\" can not be unregistered: %s",
+		  (int)mod->name.slen, mod->name.ptr, errmsg));
+    }
+
+    return status;
+}
+
+static pj_status_t unload_module(pjsip_endpoint *endpt,
+				 pjsip_module *mod)
+{
+    pj_status_t status;
+
+    /* Try to unload the module. */
+    if (mod->unload) {
+	status = (*mod->unload)();
+	if (status != PJ_SUCCESS) 
+	    return status;
+    }
+
+    /* Module MUST NOT set module ID to -1. */
+    pj_assert(mod->id >= 0);
+
+    /* Remove module from array. */
+    endpt->modules[mod->id] = NULL;
+
+    /* Remove module from list. */
+    pj_list_erase(mod);
+
+    /* Set module Id to -1. */
+    mod->id = -1;
+
+    /* Done. */
+    status = PJ_SUCCESS;
+
+    PJ_LOG(4,(THIS_FILE, "Module \"%.*s\" unregistered", 
+	      (int)mod->name.slen, mod->name.ptr));
+
+    return status;
+}
+
+
+/*
+ * Get the value of the specified capability header field.
+ */
+PJ_DEF(const pjsip_hdr*) pjsip_endpt_get_capability( pjsip_endpoint *endpt,
+						     int htype,
+						     const pj_str_t *hname)
+{
+    pjsip_hdr *hdr = endpt->cap_hdr.next;
+
+    /* Check arguments. */
+    PJ_ASSERT_RETURN(endpt != NULL, NULL);
+    PJ_ASSERT_RETURN(htype != PJSIP_H_OTHER || hname, NULL);
+
+    if (htype != PJSIP_H_OTHER) {
+	while (hdr != &endpt->cap_hdr) {
+	    if (hdr->type == htype)
+		return hdr;
+	    hdr = hdr->next;
+	}
+    }
+    return NULL;
+}
+
+
+/*
+ * Check if the specified capability is supported.
+ */
+PJ_DEF(pj_bool_t) pjsip_endpt_has_capability( pjsip_endpoint *endpt,
+					      int htype,
+					      const pj_str_t *hname,
+					      const pj_str_t *token)
+{
+    const pjsip_generic_array_hdr *hdr;
+    unsigned i;
+
+    hdr = (const pjsip_generic_array_hdr*) 
+	   pjsip_endpt_get_capability(endpt, htype, hname);
+    if (!hdr)
+	return PJ_FALSE;
+
+    PJ_ASSERT_RETURN(token != NULL, PJ_FALSE);
+
+    for (i=0; i<hdr->count; ++i) {
+	if (!pj_stricmp(&hdr->values[i], token))
+	    return PJ_TRUE;
+    }
+
+    return PJ_FALSE;
+}
+
+/*
+ * Add or register new capabilities as indicated by the tags to the
+ * appropriate header fields in the endpoint.
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_add_capability( pjsip_endpoint *endpt,
+						pjsip_module *mod,
+						int htype,
+						const pj_str_t *hname,
+						unsigned count,
+						const pj_str_t tags[])
+{
+    pjsip_generic_array_hdr *hdr;
+    unsigned i;
+
+    PJ_UNUSED_ARG(mod);
+
+    /* Check arguments. */
+    PJ_ASSERT_RETURN(endpt!=NULL && count>0 && tags, PJ_EINVAL);
+    PJ_ASSERT_RETURN(htype==PJSIP_H_ACCEPT || 
+		     htype==PJSIP_H_ALLOW ||
+		     htype==PJSIP_H_SUPPORTED,
+		     PJ_EINVAL);
+
+    /* Find the header. */
+    hdr = (pjsip_generic_array_hdr*) pjsip_endpt_get_capability(endpt, 
+								htype, hname);
+
+    /* Create the header when it's not present */
+    if (hdr == NULL) {
+	switch (htype) {
+	case PJSIP_H_ACCEPT:
+	    hdr = pjsip_accept_hdr_create(endpt->pool);
+	    break;
+	case PJSIP_H_ALLOW:
+	    hdr = pjsip_allow_hdr_create(endpt->pool);
+	    break;
+	case PJSIP_H_SUPPORTED:
+	    hdr = pjsip_supported_hdr_create(endpt->pool);
+	    break;
+	default:
+	    return PJ_EINVAL;
+	}
+
+	if (hdr) {
+	    pj_list_push_back(&endpt->cap_hdr, hdr);
+	}
+    }
+
+    /* Add the tags to the header. */
+    for (i=0; i<count; ++i) {
+	pj_strdup(endpt->pool, &hdr->values[hdr->count], &tags[i]);
+	++hdr->count;
+    }
+
+    /* Done. */
+    return PJ_SUCCESS;
+}
+
+/*
+ * Get additional headers to be put in outgoing request message.
+ */
+PJ_DEF(const pjsip_hdr*) pjsip_endpt_get_request_headers(pjsip_endpoint *endpt)
+{
+    return &endpt->req_hdr;
+}
+
+
+/*
+ * Initialize endpoint.
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,
+				       const char *name,
+                                       pjsip_endpoint **p_endpt)
+{
+    pj_status_t status;
+    pj_pool_t *pool;
+    pjsip_endpoint *endpt;
+    pjsip_max_fwd_hdr *mf_hdr;
+    pj_lock_t *lock = NULL;
+
+
+    status = pj_register_strerror(PJSIP_ERRNO_START, PJ_ERRNO_SPACE_SIZE,
+				  &pjsip_strerror);
+    pj_assert(status == PJ_SUCCESS);
+
+    PJ_LOG(5, (THIS_FILE, "Creating endpoint instance..."));
+
+    *p_endpt = NULL;
+
+    /* Create pool */
+    pool = pj_pool_create(pf, "pept%p", 
+			  PJSIP_POOL_LEN_ENDPT, PJSIP_POOL_INC_ENDPT,
+			  &pool_callback);
+    if (!pool)
+	return PJ_ENOMEM;
+
+    /* Create endpoint. */
+    endpt = PJ_POOL_ZALLOC_T(pool, pjsip_endpoint);
+    endpt->pool = pool;
+    endpt->pf = pf;
+
+    /* Init modules list. */
+    pj_list_init(&endpt->module_list);
+
+    /* Initialize exit callback list. */
+    pj_list_init(&endpt->exit_cb_list);
+
+    /* Create R/W mutex for module manipulation. */
+    status = pj_rwmutex_create(endpt->pool, "ept%p", &endpt->mod_mutex);
+    if (status != PJ_SUCCESS)
+	goto on_error;
+
+    /* Init parser. */
+    init_sip_parser();
+
+    /* Init tel: uri */
+    pjsip_tel_uri_subsys_init();
+
+    /* Get name. */
+    if (name != NULL) {
+	pj_str_t temp;
+	pj_strdup_with_null(endpt->pool, &endpt->name, pj_cstr(&temp, name));
+    } else {
+	pj_strdup_with_null(endpt->pool, &endpt->name, pj_gethostname());
+    }
+
+    /* Create mutex for the events, etc. */
+    status = pj_mutex_create_recursive( endpt->pool, "ept%p", &endpt->mutex );
+    if (status != PJ_SUCCESS) {
+	goto on_error;
+    }
+
+    /* Create timer heap to manage all timers within this endpoint. */
+    status = pj_timer_heap_create( endpt->pool, PJSIP_MAX_TIMER_COUNT, 
+                                   &endpt->timer_heap);
+    if (status != PJ_SUCCESS) {
+	goto on_error;
+    }
+
+    /* Set recursive lock for the timer heap. */
+    status = pj_lock_create_recursive_mutex( endpt->pool, "edpt%p", &lock);
+    if (status != PJ_SUCCESS) {
+	goto on_error;
+    }
+    pj_timer_heap_set_lock(endpt->timer_heap, lock, PJ_TRUE);
+
+    /* Set maximum timed out entries to process in a single poll. */
+    pj_timer_heap_set_max_timed_out_per_poll(endpt->timer_heap, 
+					     PJSIP_MAX_TIMED_OUT_ENTRIES);
+
+    /* Create ioqueue. */
+    status = pj_ioqueue_create( endpt->pool, PJSIP_MAX_TRANSPORTS, &endpt->ioqueue);
+    if (status != PJ_SUCCESS) {
+	goto on_error;
+    }
+
+    /* Create transport manager. */
+    status = pjsip_tpmgr_create( endpt->pool, endpt,
+			         &endpt_on_rx_msg,
+				 &endpt_on_tx_msg,
+				 &endpt->transport_mgr);
+    if (status != PJ_SUCCESS) {
+	goto on_error;
+    }
+
+    /* Create asynchronous DNS resolver. */
+    status = pjsip_resolver_create(endpt->pool, &endpt->resolver);
+    if (status != PJ_SUCCESS) {
+	PJ_LOG(4, (THIS_FILE, "Error creating resolver instance"));
+	goto on_error;
+    }
+
+    /* Initialize request headers. */
+    pj_list_init(&endpt->req_hdr);
+
+    /* Add "Max-Forwards" for request header. */
+    mf_hdr = pjsip_max_fwd_hdr_create(endpt->pool,
+				      PJSIP_MAX_FORWARDS_VALUE);
+    pj_list_insert_before( &endpt->req_hdr, mf_hdr);
+
+    /* Initialize capability header list. */
+    pj_list_init(&endpt->cap_hdr);
+
+
+    /* Done. */
+    *p_endpt = endpt;
+    return status;
+
+on_error:
+    if (endpt->transport_mgr) {
+	pjsip_tpmgr_destroy(endpt->transport_mgr);
+	endpt->transport_mgr = NULL;
+    }
+    if (endpt->ioqueue) {
+	pj_ioqueue_destroy(endpt->ioqueue);
+	endpt->ioqueue = NULL;
+    }
+    if (endpt->timer_heap) {
+	pj_timer_heap_destroy(endpt->timer_heap);
+	endpt->timer_heap = NULL;
+    }
+    if (endpt->mutex) {
+	pj_mutex_destroy(endpt->mutex);
+	endpt->mutex = NULL;
+    }
+    deinit_sip_parser();
+    if (endpt->mod_mutex) {
+	pj_rwmutex_destroy(endpt->mod_mutex);
+	endpt->mod_mutex = NULL;
+    }
+    pj_pool_release( endpt->pool );
+
+    PJ_LOG(4, (THIS_FILE, "Error creating endpoint"));
+    return status;
+}
+
+/*
+ * Destroy endpoint.
+ */
+PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt)
+{
+    pjsip_module *mod;
+    exit_cb *ecb;
+
+    PJ_LOG(5, (THIS_FILE, "Destroying endpoing instance.."));
+
+    /* Phase 1: stop all modules */
+    mod = endpt->module_list.prev;
+    while (mod != &endpt->module_list) {
+	pjsip_module *prev = mod->prev;
+	if (mod->stop) {
+	    (*mod->stop)();
+	}
+	mod = prev;
+    }
+
+    /* Phase 2: unload modules. */
+    mod = endpt->module_list.prev;
+    while (mod != &endpt->module_list) {
+	pjsip_module *prev = mod->prev;
+	unload_module(endpt, mod);
+	mod = prev;
+    }
+
+    /* Destroy resolver */
+    pjsip_resolver_destroy(endpt->resolver);
+
+    /* Shutdown and destroy all transports. */
+    pjsip_tpmgr_destroy(endpt->transport_mgr);
+
+    /* Destroy ioqueue */
+    pj_ioqueue_destroy(endpt->ioqueue);
+
+    /* Destroy timer heap */
+#if PJ_TIMER_DEBUG
+    pj_timer_heap_dump(endpt->timer_heap);
+#endif
+    pj_timer_heap_destroy(endpt->timer_heap);
+
+    /* Call all registered exit callbacks */
+    ecb = endpt->exit_cb_list.next;
+    while (ecb != &endpt->exit_cb_list) {
+	(*ecb->func)(endpt);
+	ecb = ecb->next;
+    }
+
+    /* Delete endpoint mutex. */
+    pj_mutex_destroy(endpt->mutex);
+
+    /* Deinit parser */
+    deinit_sip_parser();
+
+    /* Delete module's mutex */
+    pj_rwmutex_destroy(endpt->mod_mutex);
+
+    /* Finally destroy pool. */
+    pj_pool_release(endpt->pool);
+
+    PJ_LOG(4, (THIS_FILE, "Endpoint %p destroyed", endpt));
+}
+
+/*
+ * Get endpoint name.
+ */
+PJ_DEF(const pj_str_t*) pjsip_endpt_name(const pjsip_endpoint *endpt)
+{
+    return &endpt->name;
+}
+
+
+/*
+ * Create new pool.
+ */
+PJ_DEF(pj_pool_t*) pjsip_endpt_create_pool( pjsip_endpoint *endpt,
+					       const char *pool_name,
+					       pj_size_t initial,
+					       pj_size_t increment )
+{
+    pj_pool_t *pool;
+
+    /* Lock endpoint mutex. */
+    /* No need to lock mutex. Factory is thread safe.
+    pj_mutex_lock(endpt->mutex);
+     */
+
+    /* Create pool */
+    pool = pj_pool_create( endpt->pf, pool_name,
+			   initial, increment, &pool_callback);
+
+    /* Unlock mutex. */
+    /* No need to lock mutex. Factory is thread safe.
+    pj_mutex_unlock(endpt->mutex);
+     */
+
+    if (!pool) {
+	PJ_LOG(4, (THIS_FILE, "Unable to create pool %s!", pool_name));
+    }
+
+    return pool;
+}
+
+/*
+ * Return back pool to endpoint's pool manager to be either destroyed or
+ * recycled.
+ */
+PJ_DEF(void) pjsip_endpt_release_pool( pjsip_endpoint *endpt, pj_pool_t *pool )
+{
+    PJ_LOG(6, (THIS_FILE, "Releasing pool %s", pj_pool_getobjname(pool)));
+
+    /* Don't need to acquire mutex since pool factory is thread safe
+       pj_mutex_lock(endpt->mutex);
+     */
+    pj_pool_release( pool );
+
+    PJ_UNUSED_ARG(endpt);
+    /*
+    pj_mutex_unlock(endpt->mutex);
+     */
+}
+
+
+PJ_DEF(pj_status_t) pjsip_endpt_handle_events2(pjsip_endpoint *endpt,
+					       const pj_time_val *max_timeout,
+					       unsigned *p_count)
+{
+    /* timeout is 'out' var. This just to make compiler happy. */
+    pj_time_val timeout = { 0, 0};
+    unsigned count = 0, net_event_count = 0;
+    int c;
+
+    PJ_LOG(6, (THIS_FILE, "pjsip_endpt_handle_events()"));
+
+    /* Poll the timer. The timer heap has its own mutex for better 
+     * granularity, so we don't need to lock end endpoint. 
+     */
+    timeout.sec = timeout.msec = 0;
+    c = pj_timer_heap_poll( endpt->timer_heap, &timeout );
+    if (c > 0)
+	count += c;
+
+    /* timer_heap_poll should never ever returns negative value, or otherwise
+     * ioqueue_poll() will block forever!
+     */
+    pj_assert(timeout.sec >= 0 && timeout.msec >= 0);
+    if (timeout.msec >= 1000) timeout.msec = 999;
+
+    /* If caller specifies maximum time to wait, then compare the value with
+     * the timeout to wait from timer, and use the minimum value.
+     */
+    if (max_timeout && PJ_TIME_VAL_GT(timeout, *max_timeout)) {
+	timeout = *max_timeout;
+    }
+
+    /* Poll ioqueue. 
+     * Repeat polling the ioqueue while we have immediate events, because
+     * timer heap may process more than one events, so if we only process
+     * one network events at a time (such as when IOCP backend is used),
+     * the ioqueue may have trouble keeping up with the request rate.
+     *
+     * For example, for each send() request, one network event will be
+     *   reported by ioqueue for the send() completion. If we don't poll
+     *   the ioqueue often enough, the send() completion will not be
+     *   reported in timely manner.
+     */
+    do {
+	c = pj_ioqueue_poll( endpt->ioqueue, &timeout);
+	if (c < 0) {
+	    pj_status_t err = pj_get_netos_error();
+	    pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout));
+	    if (p_count)
+		*p_count = count;
+	    return err;
+	} else if (c == 0) {
+	    break;
+	} else {
+	    net_event_count += c;
+	    timeout.sec = timeout.msec = 0;
+	}
+    } while (c > 0 && net_event_count < PJSIP_MAX_NET_EVENTS);
+
+    count += net_event_count;
+    if (p_count)
+	*p_count = count;
+
+    return PJ_SUCCESS;
+}
+
+/*
+ * Handle events.
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_handle_events(pjsip_endpoint *endpt,
+					      const pj_time_val *max_timeout)
+{
+    return pjsip_endpt_handle_events2(endpt, max_timeout, NULL);
+}
+
+/*
+ * Schedule timer.
+ */
+#if PJ_TIMER_DEBUG
+PJ_DEF(pj_status_t) pjsip_endpt_schedule_timer_dbg(pjsip_endpoint *endpt,
+						    pj_timer_entry *entry,
+						    const pj_time_val *delay,
+						    const char *src_file,
+						    int src_line)
+{
+    PJ_LOG(6, (THIS_FILE, "pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)",
+			 entry, delay->sec, delay->msec));
+    return pj_timer_heap_schedule_dbg(endpt->timer_heap, entry, delay,
+                                      src_file, src_line);
+}
+#else
+PJ_DEF(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt,
+						pj_timer_entry *entry,
+						const pj_time_val *delay )
+{
+    PJ_LOG(6, (THIS_FILE, "pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)",
+			 entry, delay->sec, delay->msec));
+    return pj_timer_heap_schedule( endpt->timer_heap, entry, delay );
+}
+#endif
+
+/*
+ * Cancel the previously registered timer.
+ */
+PJ_DEF(void) pjsip_endpt_cancel_timer( pjsip_endpoint *endpt, 
+				       pj_timer_entry *entry )
+{
+    PJ_LOG(6, (THIS_FILE, "pjsip_endpt_cancel_timer(entry=%p)", entry));
+    pj_timer_heap_cancel( endpt->timer_heap, entry );
+}
+
+/*
+ * Get the timer heap instance of the SIP endpoint.
+ */
+PJ_DEF(pj_timer_heap_t*) pjsip_endpt_get_timer_heap(pjsip_endpoint *endpt)
+{
+    return endpt->timer_heap;
+}
+
+/* Init with default */
+PJ_DEF(void) pjsip_process_rdata_param_default(pjsip_process_rdata_param *p)
+{
+    pj_bzero(p, sizeof(*p));
+}
+
+/* Distribute rdata */
+PJ_DEF(pj_status_t) pjsip_endpt_process_rx_data( pjsip_endpoint *endpt,
+                                                 pjsip_rx_data *rdata,
+                                                 pjsip_process_rdata_param *p,
+                                                 pj_bool_t *p_handled)
+{
+    pjsip_msg *msg;
+    pjsip_process_rdata_param def_prm;
+    pjsip_module *mod;
+    pj_bool_t handled = PJ_FALSE;
+    unsigned i;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(endpt && rdata, PJ_EINVAL);
+
+    if (p==NULL) {
+	p = &def_prm;
+	pjsip_process_rdata_param_default(p);
+    }
+
+    msg = rdata->msg_info.msg;
+
+    if (p_handled)
+	*p_handled = PJ_FALSE;
+
+    if (!p->silent) {
+	PJ_LOG(5, (THIS_FILE, "Distributing rdata to modules: %s",
+		   pjsip_rx_data_get_info(rdata)));
+	pj_log_push_indent();
+    }
+
+    LOCK_MODULE_ACCESS(endpt);
+
+    /* Find start module */
+    if (p->start_mod) {
+	mod = (pjsip_module*)
+	      pj_list_find_node(&endpt->module_list, p->start_mod);
+	if (!mod) {
+	    status = PJ_ENOTFOUND;
+	    goto on_return;
+	}
+    } else {
+	mod = endpt->module_list.next;
+    }
+
+    /* Start after the specified index */
+    for (i=0; i < p->idx_after_start && mod != &endpt->module_list; ++i) {
+	mod = mod->next;
+    }
+
+    /* Start with the specified priority */
+    while (mod != &endpt->module_list && mod->priority < (int)p->start_prio) {
+	mod = mod->next;
+    }
+
+    if (mod == &endpt->module_list) {
+	status = PJ_ENOTFOUND;
+	goto on_return;
+    }
+
+    /* Distribute */
+    if (msg->type == PJSIP_REQUEST_MSG) {
+	do {
+	    if (mod->on_rx_request)
+		handled = (*mod->on_rx_request)(rdata);
+	    if (handled)
+		break;
+	    mod = mod->next;
+	} while (mod != &endpt->module_list);
+    } else {
+	do {
+	    if (mod->on_rx_response)
+		handled = (*mod->on_rx_response)(rdata);
+	    if (handled)
+		break;
+	    mod = mod->next;
+	} while (mod != &endpt->module_list);
+    }
+
+    status = PJ_SUCCESS;
+
+on_return:
+    if (p_handled)
+	*p_handled = handled;
+
+    UNLOCK_MODULE_ACCESS(endpt);
+    if (!p->silent) {
+	pj_log_pop_indent();
+    }
+    return status;
+}
+
+/*
+ * This is the callback that is called by the transport manager when it 
+ * receives a message from the network.
+ */
+static void endpt_on_rx_msg( pjsip_endpoint *endpt,
+			     pj_status_t status,
+			     pjsip_rx_data *rdata )
+{
+    pjsip_msg *msg = rdata->msg_info.msg;
+    pjsip_process_rdata_param proc_prm;
+    pj_bool_t handled = PJ_FALSE;
+
+    PJ_UNUSED_ARG(msg);
+
+    if (status != PJ_SUCCESS) {
+	char info[30];
+	char errmsg[PJ_ERR_MSG_SIZE];
+
+	info[0] = '\0';
+
+	if (status == PJSIP_EMISSINGHDR) {
+	    pj_str_t p;
+
+	    p.ptr = info; p.slen = 0;
+
+	    if (rdata->msg_info.cid == NULL || rdata->msg_info.cid->id.slen)
+		pj_strcpy2(&p, "Call-ID");
+	    if (rdata->msg_info.from == NULL)
+		pj_strcpy2(&p, " From");
+	    if (rdata->msg_info.to == NULL)
+		pj_strcpy2(&p, " To");
+	    if (rdata->msg_info.via == NULL)
+		pj_strcpy2(&p, " Via");
+	    if (rdata->msg_info.cseq == NULL) 
+		pj_strcpy2(&p, " CSeq");
+
+	    p.ptr[p.slen] = '\0';
+	}
+
+	pj_strerror(status, errmsg, sizeof(errmsg));
+
+	PJ_LOG(1, (THIS_FILE, 
+		  "Error processing packet from %s:%d: %s %s [code %d]:\n"
+		  "%.*s\n"
+		  "-- end of packet.",
+		  rdata->pkt_info.src_name, 
+		  rdata->pkt_info.src_port,
+		  errmsg,
+		  info,
+		  status,
+		  (int)rdata->msg_info.len,	
+		  rdata->msg_info.msg_buf));
+	return;
+    }
+
+    PJ_LOG(5, (THIS_FILE, "Processing incoming message: %s", 
+	       pjsip_rx_data_get_info(rdata)));
+    pj_log_push_indent();
+
+#if defined(PJSIP_CHECK_VIA_SENT_BY) && PJSIP_CHECK_VIA_SENT_BY != 0
+    /* For response, check that the value in Via sent-by match the transport.
+     * If not matched, silently drop the response.
+     * Ref: RFC3261 Section 18.1.2 Receiving Response
+     */
+    if (msg->type == PJSIP_RESPONSE_MSG) {
+	const pj_str_t *local_addr;
+	int port = rdata->msg_info.via->sent_by.port;
+	pj_bool_t mismatch = PJ_FALSE;
+	if (port == 0) {
+	    pjsip_transport_type_e type;
+	    type = (pjsip_transport_type_e)rdata->tp_info.transport->key.type;
+	    port = pjsip_transport_get_default_port_for_type(type);
+	}
+	local_addr = &rdata->tp_info.transport->local_name.host;
+
+	if (pj_strcmp(&rdata->msg_info.via->sent_by.host, local_addr) != 0) {
+
+	    /* The RFC says that we should drop response when sent-by
+	     * address mismatch. But it could happen (e.g. with SER) when
+	     * endpoint with private IP is sending request to public
+	     * server.
+
+	    mismatch = PJ_TRUE;
+
+	     */
+
+	} else if (port != rdata->tp_info.transport->local_name.port) {
+	    /* Port or address mismatch, we should discard response */
+	    /* But we saw one implementation (we don't want to name it to 
+	     * protect the innocence) which put wrong sent-by port although
+	     * the "rport" parameter is correct.
+	     * So we discard the response only if the port doesn't match
+	     * both the port in sent-by and rport. We try to be lenient here!
+	     */
+	    if (rdata->msg_info.via->rport_param != 
+		rdata->tp_info.transport->local_name.port)
+		mismatch = PJ_TRUE;
+	    else {
+		PJ_LOG(4,(THIS_FILE, "Message %s from %s has mismatch port in "
+				     "sent-by but the rport parameter is "
+				     "correct",
+				     pjsip_rx_data_get_info(rdata), 
+				     rdata->pkt_info.src_name));
+	    }
+	}
+
+	if (mismatch) {
+	    PJ_TODO(ENDPT_REPORT_WHEN_DROPPING_MESSAGE);
+	    PJ_LOG(4,(THIS_FILE, "Dropping response %s from %s:%d because "
+				 "sent-by is mismatch", 
+				 pjsip_rx_data_get_info(rdata),
+				 rdata->pkt_info.src_name, 
+				 rdata->pkt_info.src_port));
+	    pj_log_pop_indent();
+	    return;
+	}
+    }
+#endif
+
+    pjsip_process_rdata_param_default(&proc_prm);
+    proc_prm.silent = PJ_TRUE;
+
+    pjsip_endpt_process_rx_data(endpt, rdata, &proc_prm, &handled);
+
+    /* No module is able to handle the message */
+    if (!handled) {
+	PJ_LOG(4,(THIS_FILE, "%s from %s:%d was dropped/unhandled by"
+			     " any modules",
+			     pjsip_rx_data_get_info(rdata),
+			     rdata->pkt_info.src_name,
+			     rdata->pkt_info.src_port));
+    }
+
+    /* Must clear mod_data before returning rdata to transport, since
+     * rdata may be reused.
+     */
+    pj_bzero(&rdata->endpt_info, sizeof(rdata->endpt_info));
+
+    pj_log_pop_indent();
+}
+
+/*
+ * This callback is called by transport manager before message is sent.
+ * Modules may inspect the message before it's actually sent.
+ */
+static pj_status_t endpt_on_tx_msg( pjsip_endpoint *endpt,
+				    pjsip_tx_data *tdata )
+{
+    pj_status_t status = PJ_SUCCESS;
+    pjsip_module *mod;
+
+    /* Distribute to modules, starting from modules with LOWEST priority */
+    LOCK_MODULE_ACCESS(endpt);
+
+    mod = endpt->module_list.prev;
+    if (tdata->msg->type == PJSIP_REQUEST_MSG) {
+	while (mod != &endpt->module_list) {
+	    if (mod->on_tx_request)
+		status = (*mod->on_tx_request)(tdata);
+	    if (status != PJ_SUCCESS)
+		break;
+	    mod = mod->prev;
+	}
+
+    } else {
+	while (mod != &endpt->module_list) {
+	    if (mod->on_tx_response)
+		status = (*mod->on_tx_response)(tdata);
+	    if (status != PJ_SUCCESS)
+		break;
+	    mod = mod->prev;
+	}
+    }
+
+    UNLOCK_MODULE_ACCESS(endpt);
+
+    return status;
+}
+
+
+/*
+ * Create transmit data buffer.
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_create_tdata(  pjsip_endpoint *endpt,
+					       pjsip_tx_data **p_tdata)
+{
+    return pjsip_tx_data_create(endpt->transport_mgr, p_tdata);
+}
+
+/*
+ * Create the DNS resolver instance. 
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_create_resolver(pjsip_endpoint *endpt,
+						pj_dns_resolver **p_resv)
+{
+#if PJSIP_HAS_RESOLVER
+    PJ_ASSERT_RETURN(endpt && p_resv, PJ_EINVAL);
+    return pj_dns_resolver_create( endpt->pf, NULL, 0, endpt->timer_heap,
+				   endpt->ioqueue, p_resv);
+#else
+    PJ_UNUSED_ARG(endpt);
+    PJ_UNUSED_ARG(p_resv);
+    pj_assert(!"Resolver is disabled (PJSIP_HAS_RESOLVER==0)");
+    return PJ_EINVALIDOP;
+#endif
+}
+
+/*
+ * Set DNS resolver to be used by the SIP resolver.
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_set_resolver( pjsip_endpoint *endpt,
+					      pj_dns_resolver *resv)
+{
+    return pjsip_resolver_set_resolver(endpt->resolver, resv);
+}
+
+/*
+ * Get the DNS resolver being used by the SIP resolver.
+ */
+PJ_DEF(pj_dns_resolver*) pjsip_endpt_get_resolver(pjsip_endpoint *endpt)
+{
+    PJ_ASSERT_RETURN(endpt, NULL);
+    return pjsip_resolver_get_resolver(endpt->resolver);
+}
+
+/*
+ * Resolve
+ */
+PJ_DEF(void) pjsip_endpt_resolve( pjsip_endpoint *endpt,
+				  pj_pool_t *pool,
+				  pjsip_host_info *target,
+				  void *token,
+				  pjsip_resolver_callback *cb)
+{
+    pjsip_resolve( endpt->resolver, pool, target, token, cb);
+}
+
+/*
+ * Get transport manager.
+ */
+PJ_DEF(pjsip_tpmgr*) pjsip_endpt_get_tpmgr(pjsip_endpoint *endpt)
+{
+    return endpt->transport_mgr;
+}
+
+/*
+ * Get ioqueue instance.
+ */
+PJ_DEF(pj_ioqueue_t*) pjsip_endpt_get_ioqueue(pjsip_endpoint *endpt)
+{
+    return endpt->ioqueue;
+}
+
+/*
+ * Find/create transport.
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_acquire_transport(pjsip_endpoint *endpt,
+						  pjsip_transport_type_e type,
+						  const pj_sockaddr_t *remote,
+						  int addr_len,
+						  const pjsip_tpselector *sel,
+						  pjsip_transport **transport)
+{
+    return pjsip_tpmgr_acquire_transport(endpt->transport_mgr, type, 
+					 remote, addr_len, sel, transport);
+}
+
+
+/*
+ * Find/create transport.
+ */
+PJ_DEF(pj_status_t) pjsip_endpt_acquire_transport2(pjsip_endpoint *endpt,
+						   pjsip_transport_type_e type,
+						   const pj_sockaddr_t *remote,
+						   int addr_len,
+						   const pjsip_tpselector *sel,
+						   pjsip_tx_data *tdata,
+						   pjsip_transport **transport)
+{
+    return pjsip_tpmgr_acquire_transport2(endpt->transport_mgr, type, remote, 
+					  addr_len, sel, tdata, transport);
+}
+
+
+/*
+ * Report error.
+ */
+PJ_DEF(void) pjsip_endpt_log_error(  pjsip_endpoint *endpt,
+				     const char *sender,
+                                     pj_status_t error_code,
+                                     const char *format,
+                                     ... )
+{
+#if PJ_LOG_MAX_LEVEL > 0
+    char newformat[256];
+    pj_size_t len;
+    va_list marker;
+
+    va_start(marker, format);
+
+    PJ_UNUSED_ARG(endpt);
+
+    len = pj_ansi_strlen(format);
+    if (len < (int)sizeof(newformat)-30) {
+	pj_str_t errstr;
+
+	pj_ansi_strcpy(newformat, format);
+	pj_ansi_snprintf(newformat+len, sizeof(newformat)-len-1,
+			 ": [err %d] ", error_code);
+	len += pj_ansi_strlen(newformat+len);
+
+	errstr = pj_strerror( error_code, newformat+len, 
+			      sizeof(newformat)-len-1);
+
+	len += errstr.slen;
+	newformat[len] = '\0';
+
+	pj_log(sender, 1, newformat, marker);
+    } else {
+	pj_log(sender, 1, format, marker);
+    }
+
+    va_end(marker);
+#else
+    PJ_UNUSED_ARG(format);
+    PJ_UNUSED_ARG(error_code);
+    PJ_UNUSED_ARG(sender);
+    PJ_UNUSED_ARG(endpt);
+#endif
+}
+
+
+/*
+ * Dump endpoint.
+ */
+PJ_DEF(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail )
+{
+#if PJ_LOG_MAX_LEVEL >= 3
+    PJ_LOG(5, (THIS_FILE, "pjsip_endpt_dump()"));
+
+    /* Lock mutex. */
+    pj_mutex_lock(endpt->mutex);
+
+    PJ_LOG(3, (THIS_FILE, "Dumping endpoint %p:", endpt));
+    
+    /* Dumping pool factory. */
+    pj_pool_factory_dump(endpt->pf, detail);
+
+    /* Pool health. */
+    PJ_LOG(3, (THIS_FILE," Endpoint pool capacity=%u, used_size=%u",
+	       pj_pool_get_capacity(endpt->pool),
+	       pj_pool_get_used_size(endpt->pool)));
+
+    /* Resolver */
+#if PJSIP_HAS_RESOLVER
+    if (pjsip_endpt_get_resolver(endpt)) {
+	pj_dns_resolver_dump(pjsip_endpt_get_resolver(endpt), detail);
+    }
+#endif
+
+    /* Transports. 
+     */
+    pjsip_tpmgr_dump_transports( endpt->transport_mgr );
+
+    /* Timer. */
+#if PJ_TIMER_DEBUG
+    pj_timer_heap_dump(endpt->timer_heap);
+#else
+    PJ_LOG(3,(THIS_FILE, " Timer heap has %u entries", 
+			pj_timer_heap_count(endpt->timer_heap)));
+#endif
+
+    /* Unlock mutex. */
+    pj_mutex_unlock(endpt->mutex);
+#else
+    PJ_UNUSED_ARG(endpt);
+    PJ_UNUSED_ARG(detail);
+    PJ_LOG(3,(THIS_FILE, "pjsip_end_dump: can't dump because it's disabled."));
+#endif
+}
+
+
+PJ_DEF(pj_status_t) pjsip_endpt_atexit( pjsip_endpoint *endpt,
+					pjsip_endpt_exit_callback func)
+{
+    exit_cb *new_cb;
+
+    PJ_ASSERT_RETURN(endpt && func, PJ_EINVAL);
+
+    new_cb = PJ_POOL_ZALLOC_T(endpt->pool, exit_cb);
+    new_cb->func = func;
+
+    pj_mutex_lock(endpt->mutex);
+    pj_list_push_back(&endpt->exit_cb_list, new_cb);
+    pj_mutex_unlock(endpt->mutex);
+
+    return PJ_SUCCESS;
+}
diff --git a/jni/pjproject-android/.svn/pristine/58/58c5c059ce9439c22de6b03fef73b11e975dce48.svn-base b/jni/pjproject-android/.svn/pristine/58/58c5c059ce9439c22de6b03fef73b11e975dce48.svn-base
new file mode 100644
index 0000000..26740cc
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/58/58c5c059ce9439c22de6b03fef73b11e975dce48.svn-base
@@ -0,0 +1,95 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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 <pjsua2/types.hpp>
+#include "util.hpp"
+
+using namespace pj;
+using namespace std;
+
+#define THIS_FILE	"types.cpp"
+
+///////////////////////////////////////////////////////////////////////////////
+
+Error::Error()
+: status(PJ_SUCCESS), srcLine(0)
+{
+}
+
+Error::Error( pj_status_t prm_status,
+	      const string &prm_title,
+	      const string &prm_reason,
+	      const string &prm_src_file,
+	      int prm_src_line)
+: status(prm_status), title(prm_title), reason(prm_reason),
+  srcFile(prm_src_file), srcLine(prm_src_line)
+{
+    if (this->status != PJ_SUCCESS && prm_reason.empty()) {
+	char errmsg[PJ_ERR_MSG_SIZE];
+	pj_strerror(this->status, errmsg, sizeof(errmsg));
+	this->reason = errmsg;
+    }
+}
+
+string Error::info(bool multi_line) const
+{
+    string output;
+
+    if (status==PJ_SUCCESS) {
+	output = "No error";
+    } else if (!multi_line) {
+	char temp[80];
+
+	if (!title.empty()) {
+	    output += title + " error: ";
+	}
+	snprintf(temp, sizeof(temp), " (status=%d)", status);
+	output += reason + temp;
+	if (!srcFile.empty()) {
+	    output += " [";
+	    output += srcFile;
+	    snprintf(temp, sizeof(temp), ":%d]", srcLine);
+	    output += temp;
+	}
+    } else {
+	char temp[80];
+
+	if (!title.empty()) {
+	    output += string("Title:       ") + title + "\n";
+	}
+
+	snprintf(temp, sizeof(temp), "%d\n", status);
+	output += string("Code:        ") + temp;
+	output += string("Description: ") + reason + "\n";
+	if (!srcFile.empty()) {
+	    snprintf(temp, sizeof(temp), ":%d\n", srcLine);
+	    output += string("Location:    ") + srcFile + temp;
+	}
+    }
+
+    return output;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void TimeValue::fromPj(const pj_time_val &prm)
+{
+    this->sec  = prm.sec;
+    this->msec = prm.msec;
+}
+
diff --git a/jni/pjproject-android/.svn/pristine/58/58d0184753035f3ebee5e3b5d49eaa12ac8f86f1.svn-base b/jni/pjproject-android/.svn/pristine/58/58d0184753035f3ebee5e3b5d49eaa12ac8f86f1.svn-base
new file mode 100644
index 0000000..9fa4584
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/58/58d0184753035f3ebee5e3b5d49eaa12ac8f86f1.svn-base
@@ -0,0 +1,270 @@
+
+   /******************************************************************
+
+       iLBC Speech Coder ANSI-C Source Code
+
+       doCPLC.c
+
+       Copyright (C) The Internet Society (2004).
+       All Rights Reserved.
+
+   ******************************************************************/
+
+   #include <math.h>
+   #include <string.h>
+   #include <stdio.h>
+
+
+
+
+
+   #include "iLBC_define.h"
+
+   /*----------------------------------------------------------------*
+    *  Compute cross correlation and pitch gain for pitch prediction
+    *  of last subframe at given lag.
+    *---------------------------------------------------------------*/
+
+   void compCorr(
+       float *cc,      /* (o) cross correlation coefficient */
+       float *gc,      /* (o) gain */
+       float *pm,
+       float *buffer,  /* (i) signal buffer */
+       int lag,    /* (i) pitch lag */
+       int bLen,       /* (i) length of buffer */
+       int sRange      /* (i) correlation search length */
+   ){
+       int i;
+       float ftmp1, ftmp2, ftmp3;
+
+       /* Guard against getting outside buffer */
+       if ((bLen-sRange-lag)<0) {
+           sRange=bLen-lag;
+       }
+
+       ftmp1 = 0.0;
+       ftmp2 = 0.0;
+       ftmp3 = 0.0;
+       for (i=0; i<sRange; i++) {
+           ftmp1 += buffer[bLen-sRange+i] *
+               buffer[bLen-sRange+i-lag];
+           ftmp2 += buffer[bLen-sRange+i-lag] *
+                   buffer[bLen-sRange+i-lag];
+           ftmp3 += buffer[bLen-sRange+i] *
+                   buffer[bLen-sRange+i];
+       }
+
+       if (ftmp2 > 0.0) {
+           *cc = ftmp1*ftmp1/ftmp2;
+           *gc = (float)fabs(ftmp1/ftmp2);
+           *pm=(float)fabs(ftmp1)/
+               ((float)sqrt(ftmp2)*(float)sqrt(ftmp3));
+       }
+       else {
+           *cc = 0.0;
+           *gc = 0.0;
+           *pm=0.0;
+       }
+   }
+
+
+
+
+
+   /*----------------------------------------------------------------*
+    *  Packet loss concealment routine. Conceals a residual signal
+    *  and LP parameters. If no packet loss, update state.
+    *---------------------------------------------------------------*/
+
+   void doThePLC(
+       float *PLCresidual, /* (o) concealed residual */
+       float *PLClpc,      /* (o) concealed LP parameters */
+       int PLI,        /* (i) packet loss indicator
+                                  0 - no PL, 1 = PL */
+       float *decresidual, /* (i) decoded residual */
+       float *lpc,         /* (i) decoded LPC (only used for no PL) */
+       int inlag,          /* (i) pitch lag */
+       iLBC_Dec_Inst_t *iLBCdec_inst
+                           /* (i/o) decoder instance */
+   ){
+       int lag=20, randlag;
+       float gain, maxcc;
+       float use_gain;
+       float gain_comp, maxcc_comp, per, max_per=0;
+       int i, pick, use_lag;
+       float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;
+
+       /* Packet Loss */
+
+       if (PLI == 1) {
+
+           iLBCdec_inst->consPLICount += 1;
+
+           /* if previous frame not lost,
+              determine pitch pred. gain */
+
+           if (iLBCdec_inst->prevPLI != 1) {
+
+               /* Search around the previous lag to find the
+                  best pitch period */
+
+               lag=inlag-3;
+               compCorr(&maxcc, &gain, &max_per,
+                   iLBCdec_inst->prevResidual,
+                   lag, iLBCdec_inst->blockl, 60);
+               for (i=inlag-2;i<=inlag+3;i++) {
+                   compCorr(&maxcc_comp, &gain_comp, &per,
+                       iLBCdec_inst->prevResidual,
+                       i, iLBCdec_inst->blockl, 60);
+
+                   if (maxcc_comp>maxcc) {
+                       maxcc=maxcc_comp;
+
+
+
+
+
+                       gain=gain_comp;
+                       lag=i;
+                       max_per=per;
+                   }
+               }
+
+           }
+
+           /* previous frame lost, use recorded lag and periodicity */
+
+           else {
+               lag=iLBCdec_inst->prevLag;
+               max_per=iLBCdec_inst->per;
+           }
+
+           /* downscaling */
+
+           use_gain=1.0;
+           if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320)
+               use_gain=(float)0.9;
+           else if (iLBCdec_inst->consPLICount*
+                           iLBCdec_inst->blockl>2*320)
+               use_gain=(float)0.7;
+           else if (iLBCdec_inst->consPLICount*
+                           iLBCdec_inst->blockl>3*320)
+               use_gain=(float)0.5;
+           else if (iLBCdec_inst->consPLICount*
+                           iLBCdec_inst->blockl>4*320)
+               use_gain=(float)0.0;
+
+           /* mix noise and pitch repeatition */
+           ftmp=(float)sqrt(max_per);
+           if (ftmp>(float)0.7)
+               pitchfact=(float)1.0;
+           else if (ftmp>(float)0.4)
+               pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4);
+           else
+               pitchfact=0.0;
+
+
+           /* avoid repetition of same pitch cycle */
+           use_lag=lag;
+           if (lag<80) {
+               use_lag=2*lag;
+           }
+
+           /* compute concealed residual */
+
+
+
+
+
+
+           energy = 0.0;
+           for (i=0; i<iLBCdec_inst->blockl; i++) {
+
+               /* noise component */
+
+               iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) &
+                   (0x80000000L-1);
+               randlag = 50 + ((signed long) iLBCdec_inst->seed)%70;
+               pick = i - randlag;
+
+               if (pick < 0) {
+                   randvec[i] =
+                       iLBCdec_inst->prevResidual[
+                                   iLBCdec_inst->blockl+pick];
+               } else {
+                   randvec[i] =  randvec[pick];
+               }
+
+               /* pitch repeatition component */
+               pick = i - use_lag;
+
+               if (pick < 0) {
+                   PLCresidual[i] =
+                       iLBCdec_inst->prevResidual[
+                                   iLBCdec_inst->blockl+pick];
+               } else {
+                   PLCresidual[i] = PLCresidual[pick];
+               }
+
+               /* mix random and periodicity component */
+
+               if (i<80)
+                   PLCresidual[i] = use_gain*(pitchfact *
+                               PLCresidual[i] +
+                               ((float)1.0 - pitchfact) * randvec[i]);
+               else if (i<160)
+                   PLCresidual[i] = (float)0.95*use_gain*(pitchfact *
+                               PLCresidual[i] +
+                               ((float)1.0 - pitchfact) * randvec[i]);
+               else
+                   PLCresidual[i] = (float)0.9*use_gain*(pitchfact *
+                               PLCresidual[i] +
+                               ((float)1.0 - pitchfact) * randvec[i]);
+
+               energy += PLCresidual[i] * PLCresidual[i];
+           }
+
+           /* less than 30 dB, use only noise */
+
+
+
+
+
+
+           if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) {
+               gain=0.0;
+               for (i=0; i<iLBCdec_inst->blockl; i++) {
+                   PLCresidual[i] = randvec[i];
+               }
+           }
+
+           /* use old LPC */
+
+           memcpy(PLClpc,iLBCdec_inst->prevLpc,
+               (LPC_FILTERORDER+1)*sizeof(float));
+
+       }
+
+       /* no packet loss, copy input */
+
+       else {
+           memcpy(PLCresidual, decresidual,
+               iLBCdec_inst->blockl*sizeof(float));
+           memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float));
+           iLBCdec_inst->consPLICount = 0;
+       }
+
+       /* update state */
+
+       if (PLI) {
+           iLBCdec_inst->prevLag = lag;
+           iLBCdec_inst->per=max_per;
+       }
+
+       iLBCdec_inst->prevPLI = PLI;
+       memcpy(iLBCdec_inst->prevLpc, PLClpc,
+           (LPC_FILTERORDER+1)*sizeof(float));
+       memcpy(iLBCdec_inst->prevResidual, PLCresidual,
+           iLBCdec_inst->blockl*sizeof(float));
+   }
+