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

We will remove it once the next release of pjsip (with Android support)
comes out and is merged into SFLphone.
diff --git a/jni/pjproject-android/.svn/pristine/7d/7d4a232002c6aa0da3e9d9ac66ee211bf3755c3f.svn-base b/jni/pjproject-android/.svn/pristine/7d/7d4a232002c6aa0da3e9d9ac66ee211bf3755c3f.svn-base
new file mode 100644
index 0000000..99ad54e
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/7d/7d4a232002c6aa0da3e9d9ac66ee211bf3755c3f.svn-base
@@ -0,0 +1,1035 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2011-2013 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2011 Dan Arrhenius <dan@keystream.se>
+ *
+ * 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 
+ */
+
+/* 
+ * AMR codec implementation with OpenCORE AMR library
+ */
+#include <pjmedia-codec/g722.h>
+#include <pjmedia-codec/amr_sdp_match.h>
+#include <pjmedia/codec.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/endpoint.h>
+#include <pjmedia/plc.h>
+#include <pjmedia/port.h>
+#include <pjmedia/silencedet.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+#include <pj/os.h>
+#include <pj/math.h>
+
+#if defined(PJMEDIA_HAS_OPENCORE_AMRNB_CODEC) && \
+    (PJMEDIA_HAS_OPENCORE_AMRNB_CODEC != 0)
+#define USE_AMRNB
+#endif
+
+#if defined(PJMEDIA_HAS_OPENCORE_AMRWB_CODEC) && \
+    (PJMEDIA_HAS_OPENCORE_AMRWB_CODEC != 0)
+#define USE_AMRWB
+#endif
+
+#if defined(USE_AMRNB) || defined(USE_AMRWB)
+
+#ifdef USE_AMRNB
+#include <opencore-amrnb/interf_enc.h>
+#include <opencore-amrnb/interf_dec.h>
+#endif
+
+#ifdef USE_AMRWB
+#include <vo-amrwbenc/enc_if.h>
+#include <opencore-amrwb/dec_if.h>
+#endif
+
+#include <pjmedia-codec/amr_helper.h>
+#include <pjmedia-codec/opencore_amr.h>
+
+#define THIS_FILE "opencore_amr.c"
+
+/* Tracing */
+#define PJ_TRACE    0
+
+#if PJ_TRACE
+#   define TRACE_(expr)	PJ_LOG(4,expr)
+#else
+#   define TRACE_(expr)
+#endif
+
+/* Use PJMEDIA PLC */
+#define USE_PJMEDIA_PLC	    1
+
+#define FRAME_LENGTH_MS     20
+
+
+/* Prototypes for AMR factory */
+static pj_status_t amr_test_alloc(pjmedia_codec_factory *factory, 
+				   const pjmedia_codec_info *id );
+static pj_status_t amr_default_attr(pjmedia_codec_factory *factory, 
+				     const pjmedia_codec_info *id, 
+				     pjmedia_codec_param *attr );
+static pj_status_t amr_enum_codecs(pjmedia_codec_factory *factory, 
+				    unsigned *count, 
+				    pjmedia_codec_info codecs[]);
+static pj_status_t amr_alloc_codec(pjmedia_codec_factory *factory, 
+				    const pjmedia_codec_info *id, 
+				    pjmedia_codec **p_codec);
+static pj_status_t amr_dealloc_codec(pjmedia_codec_factory *factory, 
+				      pjmedia_codec *codec );
+
+/* Prototypes for AMR implementation. */
+static pj_status_t  amr_codec_init(pjmedia_codec *codec, 
+				    pj_pool_t *pool );
+static pj_status_t  amr_codec_open(pjmedia_codec *codec, 
+				    pjmedia_codec_param *attr );
+static pj_status_t  amr_codec_close(pjmedia_codec *codec );
+static pj_status_t  amr_codec_modify(pjmedia_codec *codec, 
+				      const pjmedia_codec_param *attr );
+static pj_status_t  amr_codec_parse(pjmedia_codec *codec,
+				     void *pkt,
+				     pj_size_t pkt_size,
+				     const pj_timestamp *ts,
+				     unsigned *frame_cnt,
+				     pjmedia_frame frames[]);
+static pj_status_t  amr_codec_encode(pjmedia_codec *codec, 
+				      const struct pjmedia_frame *input,
+				      unsigned output_buf_len, 
+				      struct pjmedia_frame *output);
+static pj_status_t  amr_codec_decode(pjmedia_codec *codec, 
+				      const struct pjmedia_frame *input,
+				      unsigned output_buf_len, 
+				      struct pjmedia_frame *output);
+static pj_status_t  amr_codec_recover(pjmedia_codec *codec,
+				      unsigned output_buf_len,
+				      struct pjmedia_frame *output);
+
+
+
+/* Definition for AMR codec operations. */
+static pjmedia_codec_op amr_op = 
+{
+    &amr_codec_init,
+    &amr_codec_open,
+    &amr_codec_close,
+    &amr_codec_modify,
+    &amr_codec_parse,
+    &amr_codec_encode,
+    &amr_codec_decode,
+    &amr_codec_recover
+};
+
+/* Definition for AMR codec factory operations. */
+static pjmedia_codec_factory_op amr_factory_op =
+{
+    &amr_test_alloc,
+    &amr_default_attr,
+    &amr_enum_codecs,
+    &amr_alloc_codec,
+    &amr_dealloc_codec,
+    &pjmedia_codec_opencore_amr_deinit
+};
+
+
+/* AMR factory */
+static struct amr_codec_factory
+{
+    pjmedia_codec_factory    base;
+    pjmedia_endpt	    *endpt;
+    pj_pool_t		    *pool;
+    pj_bool_t                init[2];
+} amr_codec_factory;
+
+
+/* AMR codec private data. */
+struct amr_data
+{
+    pj_pool_t		*pool;
+    unsigned             clock_rate;
+    void		*encoder;
+    void		*decoder;
+    pj_bool_t		 plc_enabled;
+    pj_bool_t		 vad_enabled;
+    int			 enc_mode;
+    pjmedia_codec_amr_pack_setting enc_setting;
+    pjmedia_codec_amr_pack_setting dec_setting;
+#if USE_PJMEDIA_PLC
+    pjmedia_plc		*plc;
+#endif
+    pj_timestamp	 last_tx;
+};
+
+/* Index for AMR tables. */
+enum
+{
+    IDX_AMR_NB,	/* Index for narrowband.    */
+    IDX_AMR_WB	/* Index for wideband.      */
+};
+
+static pjmedia_codec_amr_config def_config[2] =
+{{ /* AMR-NB */
+    PJ_FALSE,	    /* octet align	*/
+    5900	    /* bitrate		*/
+ },
+ { /* AMR-WB */
+    PJ_FALSE,	    /* octet align	*/
+    12650	    /* bitrate		*/
+ }};
+
+static const pj_uint16_t* amr_bitrates[2] =
+    {pjmedia_codec_amrnb_bitrates, pjmedia_codec_amrwb_bitrates};
+
+static const unsigned amr_bitrates_size[2] =
+{
+    PJ_ARRAY_SIZE(pjmedia_codec_amrnb_bitrates),
+    PJ_ARRAY_SIZE(pjmedia_codec_amrwb_bitrates)
+};
+
+
+/*
+ * Initialize and register AMR codec factory to pjmedia endpoint.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_opencore_amr_init( pjmedia_endpt *endpt,
+                                                     unsigned options)
+{
+    pjmedia_codec_mgr *codec_mgr;
+    pj_str_t codec_name;
+    pj_status_t status;
+
+    if (amr_codec_factory.pool != NULL)
+	return PJ_SUCCESS;
+
+    /* Create AMR codec factory. */
+    amr_codec_factory.base.op = &amr_factory_op;
+    amr_codec_factory.base.factory_data = NULL;
+    amr_codec_factory.endpt = endpt;
+#ifdef USE_AMRNB
+    amr_codec_factory.init[IDX_AMR_NB] = ((options & PJMEDIA_AMR_NO_NB) == 0);
+#else
+    amr_codec_factory.init[IDX_AMR_NB] = PJ_FALSE;
+#endif
+#ifdef USE_AMRWB
+    amr_codec_factory.init[IDX_AMR_WB] = ((options & PJMEDIA_AMR_NO_WB) == 0);
+#else
+    amr_codec_factory.init[IDX_AMR_WB] = PJ_FALSE;
+#endif
+
+    amr_codec_factory.pool = pjmedia_endpt_create_pool(endpt, "amr", 1000,
+						       1000);
+    if (!amr_codec_factory.pool)
+	return PJ_ENOMEM;
+
+    /* Get the codec manager. */
+    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
+    if (!codec_mgr) {
+	status = PJ_EINVALIDOP;
+	goto on_error;
+    }
+
+    /* Register format match callback. */
+    pj_cstr(&codec_name, "AMR");
+    status = pjmedia_sdp_neg_register_fmt_match_cb(
+					&codec_name,
+					&pjmedia_codec_amr_match_sdp);
+    if (status != PJ_SUCCESS)
+	goto on_error;
+
+    /* Register codec factory to endpoint. */
+    status = pjmedia_codec_mgr_register_factory(codec_mgr, 
+						&amr_codec_factory.base);
+    if (status != PJ_SUCCESS)
+	goto on_error;
+
+    /* Done. */
+    return PJ_SUCCESS;
+
+on_error:
+    pj_pool_release(amr_codec_factory.pool);
+    amr_codec_factory.pool = NULL;
+    return status;
+}
+
+PJ_DEF(pj_status_t)
+pjmedia_codec_opencore_amr_init_default( pjmedia_endpt *endpt )
+{
+    return pjmedia_codec_opencore_amr_init(endpt, 0);
+}
+
+PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrnb_init( pjmedia_endpt *endpt )
+{
+    return pjmedia_codec_opencore_amr_init(endpt, PJMEDIA_AMR_NO_WB);
+}
+
+
+/*
+ * Unregister AMR codec factory from pjmedia endpoint and deinitialize
+ * the AMR codec library.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_opencore_amr_deinit(void)
+{
+    pjmedia_codec_mgr *codec_mgr;
+    pj_status_t status;
+
+    amr_codec_factory.init[IDX_AMR_NB] = PJ_FALSE;
+    amr_codec_factory.init[IDX_AMR_WB] = PJ_FALSE;
+    
+    if (amr_codec_factory.pool == NULL)
+	return PJ_SUCCESS;
+
+    /* Get the codec manager. */
+    codec_mgr = pjmedia_endpt_get_codec_mgr(amr_codec_factory.endpt);
+    if (!codec_mgr) {
+	pj_pool_release(amr_codec_factory.pool);
+	amr_codec_factory.pool = NULL;
+	return PJ_EINVALIDOP;
+    }
+
+    /* Unregister AMR codec factory. */
+    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
+						  &amr_codec_factory.base);
+    
+    /* Destroy pool. */
+    pj_pool_release(amr_codec_factory.pool);
+    amr_codec_factory.pool = NULL;
+    
+    return status;
+}
+
+PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrnb_deinit(void)
+{
+    if (amr_codec_factory.init[IDX_AMR_NB] &&
+        amr_codec_factory.init[IDX_AMR_WB])
+    {
+        PJ_LOG(4, (THIS_FILE, "Should call "
+                              "pjmedia_codec_opencore_amr_deinit() instead"));
+        
+        return PJ_EINVALIDOP;
+    }
+    
+    return pjmedia_codec_opencore_amr_deinit();
+}
+
+static pj_status_t
+amr_set_config(unsigned idx, const pjmedia_codec_amr_config *config)
+{
+    unsigned nbitrates;
+
+    def_config[idx] = *config;
+
+    /* Normalize bitrate. */
+    nbitrates = amr_bitrates_size[idx];
+    if (def_config[idx].bitrate < amr_bitrates[idx][0]) {
+	def_config[idx].bitrate = amr_bitrates[idx][0];
+    } else if (def_config[idx].bitrate > amr_bitrates[idx][nbitrates-1]) {
+	def_config[idx].bitrate = amr_bitrates[idx][nbitrates-1];
+    } else
+    {
+	unsigned i;
+	
+	for (i = 0; i < nbitrates; ++i) {
+	    if (def_config[idx].bitrate <= amr_bitrates[idx][i])
+		break;
+	}
+	def_config[idx].bitrate = amr_bitrates[idx][i];
+    }
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrnb_set_config(
+                                    const pjmedia_codec_amrnb_config *config)
+{
+    return amr_set_config(IDX_AMR_NB, (const pjmedia_codec_amr_config *)config);
+}
+
+PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrwb_set_config(
+                                    const pjmedia_codec_amrwb_config *config)
+{
+    return amr_set_config(IDX_AMR_WB, (const pjmedia_codec_amr_config *)config);
+}
+
+/*
+ * Check if factory can allocate the specified codec.
+ */
+static pj_status_t amr_test_alloc( pjmedia_codec_factory *factory, 
+				   const pjmedia_codec_info *info )
+{
+    const pj_str_t amr_tag = { "AMR", 3};
+    const pj_str_t amrwb_tag = { "AMR-WB", 6};
+    PJ_UNUSED_ARG(factory);
+
+    /* Type MUST be audio. */
+    if (info->type != PJMEDIA_TYPE_AUDIO)
+	return PJMEDIA_CODEC_EUNSUP;
+    
+    /* Check payload type. */
+    if (info->pt != PJMEDIA_RTP_PT_AMR && info->pt != PJMEDIA_RTP_PT_AMRWB)
+	return PJMEDIA_CODEC_EUNSUP;
+    
+    /* Check encoding name. */
+    if (pj_stricmp(&info->encoding_name, &amr_tag) != 0 &&
+        pj_stricmp(&info->encoding_name, &amrwb_tag) != 0)
+    {
+	return PJMEDIA_CODEC_EUNSUP;
+    }
+    
+    /* Check clock-rate */
+    if ((info->clock_rate == 8000 && amr_codec_factory.init[IDX_AMR_NB]) ||
+        (info->clock_rate == 16000 && amr_codec_factory.init[IDX_AMR_WB]))
+    {
+        return PJ_SUCCESS;
+    }
+
+    /* Unsupported or disabled. */
+    return PJMEDIA_CODEC_EUNSUP;
+}
+
+/*
+ * Generate default attribute.
+ */
+static pj_status_t amr_default_attr( pjmedia_codec_factory *factory, 
+				     const pjmedia_codec_info *id, 
+				     pjmedia_codec_param *attr )
+{
+    unsigned idx;
+    
+    PJ_UNUSED_ARG(factory);
+
+    idx = (id->clock_rate <= 8000? IDX_AMR_NB: IDX_AMR_WB);
+    pj_bzero(attr, sizeof(pjmedia_codec_param));
+    attr->info.clock_rate = (id->clock_rate <= 8000? 8000: 16000);
+    attr->info.channel_cnt = 1;
+    attr->info.avg_bps = def_config[idx].bitrate;
+    attr->info.max_bps = amr_bitrates[idx][amr_bitrates_size[idx]-1];
+    attr->info.pcm_bits_per_sample = 16;
+    attr->info.frm_ptime = 20;
+    attr->info.pt = (pj_uint8_t)id->pt;
+
+    attr->setting.frm_per_pkt = 1;
+    attr->setting.vad = 1;
+    attr->setting.plc = 1;
+
+    if (def_config[idx].octet_align) {
+	attr->setting.dec_fmtp.cnt = 1;
+	attr->setting.dec_fmtp.param[0].name = pj_str("octet-align");
+	attr->setting.dec_fmtp.param[0].val = pj_str("1");
+    }
+
+    /* Default all other flag bits disabled. */
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Enum codecs supported by this factory (i.e. AMR-NB and AMR-WB).
+ */
+static pj_status_t amr_enum_codecs( pjmedia_codec_factory *factory, 
+				    unsigned *count, 
+				    pjmedia_codec_info codecs[])
+{
+    PJ_UNUSED_ARG(factory);
+    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
+
+    *count = 0;
+
+    if (amr_codec_factory.init[IDX_AMR_NB]) {
+        pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));
+        codecs[*count].encoding_name = pj_str("AMR");
+        codecs[*count].pt = PJMEDIA_RTP_PT_AMR;
+        codecs[*count].type = PJMEDIA_TYPE_AUDIO;
+        codecs[*count].clock_rate = 8000;
+        codecs[*count].channel_cnt = 1;
+        (*count)++;
+    }
+    
+    if (amr_codec_factory.init[IDX_AMR_WB]) {
+        pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));
+        codecs[*count].encoding_name = pj_str("AMR-WB");
+        codecs[*count].pt = PJMEDIA_RTP_PT_AMRWB;
+        codecs[*count].type = PJMEDIA_TYPE_AUDIO;
+        codecs[*count].clock_rate = 16000;
+        codecs[*count].channel_cnt = 1;
+        (*count)++;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Allocate a new AMR codec instance.
+ */
+static pj_status_t amr_alloc_codec( pjmedia_codec_factory *factory, 
+				    const pjmedia_codec_info *id,
+				    pjmedia_codec **p_codec)
+{
+    pj_pool_t *pool;
+    pjmedia_codec *codec;
+    struct amr_data *amr_data;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
+    PJ_ASSERT_RETURN(factory == &amr_codec_factory.base, PJ_EINVAL);
+
+    pool = pjmedia_endpt_create_pool(amr_codec_factory.endpt, "amr-inst", 
+				     512, 512);
+
+    codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);
+    PJ_ASSERT_RETURN(codec != NULL, PJ_ENOMEM);
+    codec->op = &amr_op;
+    codec->factory = factory;
+
+    amr_data = PJ_POOL_ZALLOC_T(pool, struct amr_data);
+    codec->codec_data = amr_data;
+    amr_data->pool = pool;
+
+#if USE_PJMEDIA_PLC
+    /* Create PLC */
+    status = pjmedia_plc_create(pool, id->clock_rate,
+                                id->clock_rate * FRAME_LENGTH_MS / 1000, 0,
+                                &amr_data->plc);
+    if (status != PJ_SUCCESS) {
+	return status;
+    }
+#else
+    PJ_UNUSED_ARG(status);
+#endif
+    *p_codec = codec;
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Free codec.
+ */
+static pj_status_t amr_dealloc_codec( pjmedia_codec_factory *factory, 
+				      pjmedia_codec *codec )
+{
+    struct amr_data *amr_data;
+
+    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
+    PJ_ASSERT_RETURN(factory == &amr_codec_factory.base, PJ_EINVAL);
+
+    amr_data = (struct amr_data*) codec->codec_data;
+
+    /* Close codec, if it's not closed. */
+    amr_codec_close(codec);
+
+    pj_pool_release(amr_data->pool);
+    amr_data = NULL;
+
+    return PJ_SUCCESS;
+}
+
+/*
+ * Init codec.
+ */
+static pj_status_t amr_codec_init( pjmedia_codec *codec, 
+				   pj_pool_t *pool )
+{
+    PJ_UNUSED_ARG(codec);
+    PJ_UNUSED_ARG(pool);
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Open codec.
+ */
+static pj_status_t amr_codec_open( pjmedia_codec *codec, 
+				   pjmedia_codec_param *attr )
+{
+    struct amr_data *amr_data = (struct amr_data*) codec->codec_data;
+    pjmedia_codec_amr_pack_setting *setting;
+    unsigned i;
+    pj_uint8_t octet_align = 0;
+    pj_int8_t enc_mode;
+    const pj_str_t STR_FMTP_OCTET_ALIGN = {"octet-align", 11};
+    unsigned idx;
+
+    PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);
+    PJ_ASSERT_RETURN(amr_data != NULL, PJ_EINVALIDOP);
+
+    idx = (attr->info.clock_rate <= 8000? IDX_AMR_NB: IDX_AMR_WB);
+    enc_mode = pjmedia_codec_amr_get_mode(attr->info.avg_bps);
+    pj_assert(enc_mode >= 0 && enc_mode < amr_bitrates_size[idx]);
+
+    /* Check octet-align */
+    for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) {
+	if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, 
+		       &STR_FMTP_OCTET_ALIGN) == 0)
+	{
+	    octet_align = (pj_uint8_t)
+			  (pj_strtoul(&attr->setting.dec_fmtp.param[i].val));
+	    break;
+	}
+    }
+
+    /* Check mode-set */
+    for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
+	const pj_str_t STR_FMTP_MODE_SET = {"mode-set", 8};
+        
+	if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, 
+		       &STR_FMTP_MODE_SET) == 0)
+	{
+	    const char *p;
+	    pj_size_t l;
+	    pj_int8_t diff = 99;
+
+	    /* Encoding mode is chosen based on local default mode setting:
+	     * - if local default mode is included in the mode-set, use it
+	     * - otherwise, find the closest mode to local default mode;
+	     *   if there are two closest modes, prefer to use the higher
+	     *   one, e.g: local default mode is 4, the mode-set param
+	     *   contains '2,3,5,6', then 5 will be chosen.
+	     */
+	    p = pj_strbuf(&attr->setting.enc_fmtp.param[i].val);
+	    l = pj_strlen(&attr->setting.enc_fmtp.param[i].val);
+	    while (l--) {
+		if (*p>='0' && *p<=('0'+amr_bitrates_size[idx]-1)) {
+		    pj_int8_t tmp = *p - '0' - enc_mode;
+
+		    if (PJ_ABS(diff) > PJ_ABS(tmp) || 
+			(PJ_ABS(diff) == PJ_ABS(tmp) && tmp > diff))
+		    {
+			diff = tmp;
+			if (diff == 0) break;
+		    }
+		}
+		++p;
+	    }
+	    PJ_ASSERT_RETURN(diff != 99, PJMEDIA_CODEC_EFAILED);
+
+	    enc_mode = enc_mode + diff;
+
+	    break;
+	}
+    }
+
+    amr_data->clock_rate = attr->info.clock_rate;
+    amr_data->vad_enabled = (attr->setting.vad != 0);
+    amr_data->plc_enabled = (attr->setting.plc != 0);
+    amr_data->enc_mode = enc_mode;
+
+    if (idx == IDX_AMR_NB) {
+#ifdef USE_AMRNB
+        amr_data->encoder = Encoder_Interface_init(amr_data->vad_enabled);
+#endif
+    } else {
+#ifdef USE_AMRWB
+        amr_data->encoder = E_IF_init();
+#endif
+    }
+    if (amr_data->encoder == NULL) {
+	TRACE_((THIS_FILE, "Encoder initialization failed"));
+	amr_codec_close(codec);
+	return PJMEDIA_CODEC_EFAILED;
+    }
+    setting = &amr_data->enc_setting;
+    pj_bzero(setting, sizeof(pjmedia_codec_amr_pack_setting));
+    setting->amr_nb = (idx == IDX_AMR_NB? 1: 0);
+    setting->reorder = 0;
+    setting->octet_aligned = octet_align;
+    setting->cmr = 15;
+
+    if (idx == IDX_AMR_NB) {
+#ifdef USE_AMRNB
+        amr_data->decoder = Decoder_Interface_init();
+#endif
+    } else {
+#ifdef USE_AMRWB
+        amr_data->decoder = D_IF_init();
+#endif
+    }
+    if (amr_data->decoder == NULL) {
+	TRACE_((THIS_FILE, "Decoder initialization failed"));
+	amr_codec_close(codec);
+	return PJMEDIA_CODEC_EFAILED;
+    }
+    setting = &amr_data->dec_setting;
+    pj_bzero(setting, sizeof(pjmedia_codec_amr_pack_setting));
+    setting->amr_nb = (idx == IDX_AMR_NB? 1: 0);
+    setting->reorder = 0;
+    setting->octet_aligned = octet_align;
+
+    TRACE_((THIS_FILE, "AMR codec allocated: clockrate=%d vad=%d, plc=%d,"
+                       " bitrate=%d", amr_data->clock_rate,
+			amr_data->vad_enabled, amr_data->plc_enabled, 
+			amr_bitrates[idx][amr_data->enc_mode]));
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Close codec.
+ */
+static pj_status_t amr_codec_close( pjmedia_codec *codec )
+{
+    struct amr_data *amr_data;
+
+    PJ_ASSERT_RETURN(codec, PJ_EINVAL);
+
+    amr_data = (struct amr_data*) codec->codec_data;
+    PJ_ASSERT_RETURN(amr_data != NULL, PJ_EINVALIDOP);
+
+    if (amr_data->encoder) {
+        if (amr_data->enc_setting.amr_nb) {
+#ifdef USE_AMRNB
+            Encoder_Interface_exit(amr_data->encoder);
+#endif
+        } else {
+#ifdef USE_AMRWB
+            E_IF_exit(amr_data->encoder);
+#endif
+        }
+        amr_data->encoder = NULL;
+    }
+
+    if (amr_data->decoder) {
+        if (amr_data->dec_setting.amr_nb) {
+#ifdef USE_AMRNB
+            Decoder_Interface_exit(amr_data->decoder);
+#endif
+        } else {
+#ifdef USE_AMRWB
+            D_IF_exit(amr_data->decoder);
+#endif
+        }
+        amr_data->decoder = NULL;
+    }
+    
+    TRACE_((THIS_FILE, "AMR codec closed"));
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Modify codec settings.
+ */
+static pj_status_t amr_codec_modify( pjmedia_codec *codec, 
+				     const pjmedia_codec_param *attr )
+{
+    struct amr_data *amr_data = (struct amr_data*) codec->codec_data;
+    pj_bool_t prev_vad_state;
+
+    pj_assert(amr_data != NULL);
+    pj_assert(amr_data->encoder != NULL && amr_data->decoder != NULL);
+
+    prev_vad_state = amr_data->vad_enabled;
+    amr_data->vad_enabled = (attr->setting.vad != 0);
+    amr_data->plc_enabled = (attr->setting.plc != 0);
+
+    if (amr_data->enc_setting.amr_nb &&
+        prev_vad_state != amr_data->vad_enabled)
+    {
+	/* Reinit AMR encoder to update VAD setting */
+	TRACE_((THIS_FILE, "Reiniting AMR encoder to update VAD setting."));
+#ifdef USE_AMRNB
+        Encoder_Interface_exit(amr_data->encoder);
+        amr_data->encoder = Encoder_Interface_init(amr_data->vad_enabled);
+#endif
+        if (amr_data->encoder == NULL) {
+	    TRACE_((THIS_FILE, "Encoder_Interface_init() failed"));
+	    amr_codec_close(codec);
+	    return PJMEDIA_CODEC_EFAILED;
+	}
+    }
+
+    TRACE_((THIS_FILE, "AMR codec modified: vad=%d, plc=%d",
+			amr_data->vad_enabled, amr_data->plc_enabled));
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Get frames in the packet.
+ */
+static pj_status_t amr_codec_parse( pjmedia_codec *codec,
+				    void *pkt,
+				    pj_size_t pkt_size,
+				    const pj_timestamp *ts,
+				    unsigned *frame_cnt,
+				    pjmedia_frame frames[])
+{
+    struct amr_data *amr_data = (struct amr_data*) codec->codec_data;
+    pj_uint8_t cmr;
+    pj_status_t status;
+    unsigned idx = (amr_data->enc_setting.amr_nb? 0: 1);
+
+    status = pjmedia_codec_amr_parse(pkt, pkt_size, ts, &amr_data->dec_setting,
+				     frames, frame_cnt, &cmr);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Check for Change Mode Request. */
+    if (cmr < amr_bitrates_size[idx] && amr_data->enc_mode != cmr) {
+	amr_data->enc_mode = cmr;
+	TRACE_((THIS_FILE, "AMR encoder switched mode to %d (%dbps)",
+                amr_data->enc_mode, 
+                amr_bitrates[idx][amr_data->enc_mode]));
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Encode frame.
+ */
+static pj_status_t amr_codec_encode( pjmedia_codec *codec, 
+				     const struct pjmedia_frame *input,
+				     unsigned output_buf_len, 
+				     struct pjmedia_frame *output)
+{
+    struct amr_data *amr_data = (struct amr_data*) codec->codec_data;
+    unsigned char *bitstream;
+    pj_int16_t *speech;
+    unsigned nsamples, samples_per_frame;
+    enum {MAX_FRAMES_PER_PACKET = 16};
+    pjmedia_frame frames[MAX_FRAMES_PER_PACKET];
+    pj_uint8_t *p;
+    unsigned i, out_size = 0, nframes = 0;
+    pj_size_t payload_len;
+    unsigned dtx_cnt, sid_cnt;
+    pj_status_t status;
+
+    pj_assert(amr_data != NULL);
+    PJ_ASSERT_RETURN(input && output, PJ_EINVAL);
+
+    nsamples = input->size >> 1;
+    samples_per_frame = amr_data->clock_rate * FRAME_LENGTH_MS / 1000;
+    PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0, 
+		     PJMEDIA_CODEC_EPCMFRMINLEN);
+
+    nframes = nsamples / samples_per_frame;
+    PJ_ASSERT_RETURN(nframes <= MAX_FRAMES_PER_PACKET, 
+		     PJMEDIA_CODEC_EFRMTOOSHORT);
+
+    /* Encode the frames */
+    speech = (pj_int16_t*)input->buf;
+    bitstream = (unsigned char*)output->buf;
+    while (nsamples >= samples_per_frame) {
+	int size;
+        if (amr_data->enc_setting.amr_nb) {
+#ifdef USE_AMRNB
+            size = Encoder_Interface_Encode (amr_data->encoder,
+                                             amr_data->enc_mode,
+                                             speech, bitstream, 0);
+#else
+            size = 0;
+#endif
+        } else {
+#ifdef USE_AMRWB
+            size = E_IF_encode (amr_data->encoder, amr_data->enc_mode,
+                                speech, bitstream, 0);
+#else
+            size = 0;
+#endif
+        }
+	if (size == 0) {
+	    output->size = 0;
+	    output->buf = NULL;
+	    output->type = PJMEDIA_FRAME_TYPE_NONE;
+	    TRACE_((THIS_FILE, "AMR encode() failed"));
+	    return PJMEDIA_CODEC_EFAILED;
+	}
+	nsamples -= samples_per_frame;
+	speech += samples_per_frame;
+	bitstream += size;
+	out_size += size;
+	TRACE_((THIS_FILE, "AMR encode(): mode=%d, size=%d",
+		amr_data->enc_mode, out_size));
+    }
+
+    /* Pack payload */
+    p = (pj_uint8_t*)output->buf + output_buf_len - out_size;
+    pj_memmove(p, output->buf, out_size);
+    dtx_cnt = sid_cnt = 0;
+    for (i = 0; i < nframes; ++i) {
+	pjmedia_codec_amr_bit_info *info = (pjmedia_codec_amr_bit_info*)
+					   &frames[i].bit_info;
+	info->frame_type = (pj_uint8_t)((*p >> 3) & 0x0F);
+	info->good_quality = (pj_uint8_t)((*p >> 2) & 0x01);
+	info->mode = (pj_int8_t)amr_data->enc_mode;
+	info->start_bit = 0;
+	frames[i].buf = p + 1;
+        if (amr_data->enc_setting.amr_nb) {
+            frames[i].size = (info->frame_type <= 8)?
+                             pjmedia_codec_amrnb_framelen[info->frame_type] : 0;
+        } else {
+            frames[i].size = (info->frame_type <= 9)?
+                             pjmedia_codec_amrwb_framelen[info->frame_type] : 0;
+        }
+	p += frames[i].size + 1;
+
+	/* Count the number of SID and DTX frames */
+	if (info->frame_type == 15) /* DTX*/
+	    ++dtx_cnt;
+	else if (info->frame_type == 8) /* SID */
+	    ++sid_cnt;
+    }
+
+    /* VA generates DTX frames as DTX+SID frames switching quickly and it
+     * seems that the SID frames occur too often (assuming the purpose is 
+     * only for keeping NAT alive?). So let's modify the behavior a bit.
+     * Only an SID frame will be sent every PJMEDIA_CODEC_MAX_SILENCE_PERIOD
+     * milliseconds.
+     */
+    if (sid_cnt + dtx_cnt == nframes) {
+	pj_int32_t dtx_duration;
+
+	dtx_duration = pj_timestamp_diff32(&amr_data->last_tx, 
+					   &input->timestamp);
+	if (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
+	    dtx_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*
+                           amr_data->clock_rate/1000)
+	{
+	    output->size = 0;
+	    output->type = PJMEDIA_FRAME_TYPE_NONE;
+	    output->timestamp = input->timestamp;
+	    return PJ_SUCCESS;
+	}
+    }
+
+    payload_len = output_buf_len;
+
+    status = pjmedia_codec_amr_pack(frames, nframes, &amr_data->enc_setting,
+				    output->buf, &payload_len);
+    if (status != PJ_SUCCESS) {
+	output->size = 0;
+	output->buf = NULL;
+	output->type = PJMEDIA_FRAME_TYPE_NONE;
+	TRACE_((THIS_FILE, "Failed to pack AMR payload, status=%d", status));
+	return status;
+    }
+
+    output->size = payload_len;
+    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
+    output->timestamp = input->timestamp;
+
+    amr_data->last_tx = input->timestamp;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Decode frame.
+ */
+static pj_status_t amr_codec_decode( pjmedia_codec *codec, 
+				     const struct pjmedia_frame *input,
+				     unsigned output_buf_len, 
+				     struct pjmedia_frame *output)
+{
+    struct amr_data *amr_data = (struct amr_data*) codec->codec_data;
+    pjmedia_frame input_;
+    pjmedia_codec_amr_bit_info *info;
+    unsigned out_size;
+    /* AMR decoding buffer: AMR max frame size + 1 byte header. */
+    unsigned char bitstream[61];
+
+    pj_assert(amr_data != NULL);
+    PJ_ASSERT_RETURN(input && output, PJ_EINVAL);
+
+    out_size = amr_data->clock_rate * FRAME_LENGTH_MS / 1000 * 2;
+    if (output_buf_len < out_size)
+	return PJMEDIA_CODEC_EPCMTOOSHORT;
+
+    input_.buf = &bitstream[1];
+    /* AMR max frame size */
+    input_.size = (amr_data->dec_setting.amr_nb? 31: 60);
+    pjmedia_codec_amr_predecode(input, &amr_data->dec_setting, &input_);
+    info = (pjmedia_codec_amr_bit_info*)&input_.bit_info;
+
+    /* VA AMR decoder requires frame info in the first byte. */
+    bitstream[0] = (info->frame_type << 3) | (info->good_quality << 2);
+
+    TRACE_((THIS_FILE, "AMR decode(): mode=%d, ft=%d, size=%d",
+	    info->mode, info->frame_type, input_.size));
+
+    /* Decode */
+    if (amr_data->dec_setting.amr_nb) {
+#ifdef USE_AMRNB
+        Decoder_Interface_Decode(amr_data->decoder, bitstream,
+                                 (pj_int16_t*)output->buf, 0);
+#endif
+    } else {
+#ifdef USE_AMRWB
+        D_IF_decode(amr_data->decoder, bitstream,
+                    (pj_int16_t*)output->buf, 0);
+#endif
+    }
+
+    output->size = out_size;
+    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
+    output->timestamp = input->timestamp;
+
+#if USE_PJMEDIA_PLC
+    if (amr_data->plc_enabled)
+	pjmedia_plc_save(amr_data->plc, (pj_int16_t*)output->buf);
+#endif
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Recover lost frame.
+ */
+#if USE_PJMEDIA_PLC
+/*
+ * Recover lost frame.
+ */
+static pj_status_t  amr_codec_recover( pjmedia_codec *codec,
+				       unsigned output_buf_len,
+				       struct pjmedia_frame *output)
+{
+    struct amr_data *amr_data = codec->codec_data;
+    unsigned out_size = amr_data->clock_rate * FRAME_LENGTH_MS / 1000 * 2;
+
+    TRACE_((THIS_FILE, "amr_codec_recover"));
+
+    PJ_ASSERT_RETURN(amr_data->plc_enabled, PJ_EINVALIDOP);
+
+    PJ_ASSERT_RETURN(output_buf_len >= out_size,  PJMEDIA_CODEC_EPCMTOOSHORT);
+
+    pjmedia_plc_generate(amr_data->plc, (pj_int16_t*)output->buf);
+
+    output->size = out_size;
+    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
+    
+    return PJ_SUCCESS;
+}
+#endif
+
+#if defined(_MSC_VER) && PJMEDIA_AUTO_LINK_OPENCORE_AMR_LIBS
+#   if PJMEDIA_OPENCORE_AMR_BUILT_WITH_GCC
+#       ifdef USE_AMRNB
+#           pragma comment( lib, "libopencore-amrnb.a")
+#       endif
+#       ifdef USE_AMRWB
+#           pragma comment( lib, "libopencore-amrwb.a")
+#           pragma comment( lib, "libvo-amrwbenc.a")
+#       endif
+#   else
+#       error Unsupported OpenCORE AMR library, fix here
+#   endif
+#endif
+
+#endif
diff --git a/jni/pjproject-android/.svn/pristine/7d/7d6fad1679f2960c073dc419efb003a5eeae8a15.svn-base b/jni/pjproject-android/.svn/pristine/7d/7d6fad1679f2960c073dc419efb003a5eeae8a15.svn-base
new file mode 100644
index 0000000..67a8d63
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/7d/7d6fad1679f2960c073dc419efb003a5eeae8a15.svn-base
@@ -0,0 +1,138 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2009-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 <pj/ssl_sock.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/string.h>
+
+/*
+ * Initialize the SSL socket configuration with the default values.
+ */
+PJ_DEF(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param)
+{
+    pj_bzero(param, sizeof(*param));
+
+    /* Socket config */
+    param->sock_af = PJ_AF_INET;
+    param->sock_type = pj_SOCK_STREAM();
+    param->async_cnt = 1;
+    param->concurrency = -1;
+    param->whole_data = PJ_TRUE;
+    param->send_buffer_size = 8192;
+#if !defined(PJ_SYMBIAN) || PJ_SYMBIAN==0
+    param->read_buffer_size = 1500;
+#endif
+    param->qos_type = PJ_QOS_TYPE_BEST_EFFORT;
+    param->qos_ignore_error = PJ_TRUE;
+
+    /* Security config */
+    param->proto = PJ_SSL_SOCK_PROTO_DEFAULT;
+}
+
+
+PJ_DEF(pj_status_t) pj_ssl_cert_get_verify_status_strings(
+						pj_uint32_t verify_status, 
+						const char *error_strings[],
+						unsigned *count)
+{
+    unsigned i = 0, shift_idx = 0;
+    unsigned unknown = 0;
+    pj_uint32_t errs;
+
+    PJ_ASSERT_RETURN(error_strings && count, PJ_EINVAL);
+
+    if (verify_status == PJ_SSL_CERT_ESUCCESS && *count) {
+	error_strings[0] = "OK";
+	*count = 1;
+	return PJ_SUCCESS;
+    }
+
+    errs = verify_status;
+
+    while (errs && i < *count) {
+	pj_uint32_t err;
+	const char *p = NULL;
+
+	if ((errs & 1) == 0) {
+	    shift_idx++;
+	    errs >>= 1;
+	    continue;
+	}
+
+	err = (1 << shift_idx);
+
+	switch (err) {
+	case PJ_SSL_CERT_EISSUER_NOT_FOUND:
+	    p = "The issuer certificate cannot be found";
+	    break;
+	case PJ_SSL_CERT_EUNTRUSTED:
+	    p = "The certificate is untrusted";
+	    break;
+	case PJ_SSL_CERT_EVALIDITY_PERIOD:
+	    p = "The certificate has expired or not yet valid";
+	    break;
+	case PJ_SSL_CERT_EINVALID_FORMAT:
+	    p = "One or more fields of the certificate cannot be decoded "
+		"due to invalid format";
+	    break;
+	case PJ_SSL_CERT_EISSUER_MISMATCH:
+	    p = "The issuer info in the certificate does not match to the "
+		"(candidate) issuer certificate";
+	    break;
+	case PJ_SSL_CERT_ECRL_FAILURE:
+	    p = "The CRL certificate cannot be found or cannot be read "
+		"properly";
+	    break;
+	case PJ_SSL_CERT_EREVOKED:
+	    p = "The certificate has been revoked";
+	    break;
+	case PJ_SSL_CERT_EINVALID_PURPOSE:
+	    p = "The certificate or CA certificate cannot be used for the "
+		"specified purpose";
+	    break;
+	case PJ_SSL_CERT_ECHAIN_TOO_LONG:
+	    p = "The certificate chain length is too long";
+	    break;
+	case PJ_SSL_CERT_EIDENTITY_NOT_MATCH:
+	    p = "The server identity does not match to any identities "
+		"specified in the certificate";
+	    break;
+	case PJ_SSL_CERT_EUNKNOWN:
+	default:
+	    unknown++;
+	    break;
+	}
+	
+	/* Set error string */
+	if (p)
+	    error_strings[i++] = p;
+
+	/* Next */
+	shift_idx++;
+	errs >>= 1;
+    }
+
+    /* Unknown error */
+    if (unknown && i < *count)
+	error_strings[i++] = "Unknown verification error";
+
+    *count = i;
+
+    return PJ_SUCCESS;
+}
diff --git a/jni/pjproject-android/.svn/pristine/7d/7da3dbbe71d2d0f7888279f5bdbef6f483f85a75.svn-base b/jni/pjproject-android/.svn/pristine/7d/7da3dbbe71d2d0f7888279f5bdbef6f483f85a75.svn-base
new file mode 100644
index 0000000..9cd5e97
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/7d/7da3dbbe71d2d0f7888279f5bdbef6f483f85a75.svn-base
@@ -0,0 +1,135 @@
+/* $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 
+ */
+#ifndef __PJSIP_SIMPLE_ISCOMPOSING_H__
+#define __PJSIP_SIMPLE_ISCOMPOSING_H__
+
+/**
+ * @file iscomposing.h
+ * @brief Support for Indication of Message Composition (RFC 3994)
+ */
+#include <pjsip-simple/types.h>
+#include <pjlib-util/xml.h>
+
+/**
+ * @defgroup PJSIP_ISCOMPOSING Message Composition Indication (RFC 3994)
+ * @ingroup PJSIP_SIMPLE
+ * @brief Support for Indication of Message Composition (RFC 3994)
+ * @{
+ *
+ * This implements message composition indication, as described in
+ * RFC 3994.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create XML message with MIME type "application/im-iscomposing+xml"
+ * to indicate the message composition status.
+ *
+ * @param pool		    Pool to allocate memory.
+ * @param is_composing	    Message composition indication status. Set to
+ *			    PJ_TRUE (or non-zero) to indicate that application
+ *			    is currently composing an instant message.
+ * @param lst_actv	    Optional attribute to indicate time of last
+ *			    activity. If none is to be specified, the value
+ *			    MUST be set to NULL.
+ * @param content_tp	    Optional attribute to indicate the content type of
+ *			    message being composed. If none is to be specified, 
+ *			    the value MUST be set to NULL.
+ * @param refresh	    Optional attribute to indicate the interval when
+ *			    next indication will be sent, only when 
+ *			    is_composing is non-zero. If none is to be 
+ *			    specified, the value MUST be set to -1.
+ *
+ * @return		    An XML message containing the message indication.
+ *			    NULL will be returned when there's not enough
+ *			    memory to allocate the message.
+ */
+PJ_DECL(pj_xml_node*) pjsip_iscomposing_create_xml(pj_pool_t *pool,
+						   pj_bool_t is_composing,
+						   const pj_time_val *lst_actv,
+						   const pj_str_t *content_tp,
+						   int refresh);
+
+
+/**
+ * Create message body with Content-Type "application/im-iscomposing+xml"
+ * to indicate the message composition status.
+ *
+ * @param pool		    Pool to allocate memory.
+ * @param is_composing	    Message composition indication status. Set to
+ *			    PJ_TRUE (or non-zero) to indicate that application
+ *			    is currently composing an instant message.
+ * @param lst_actv	    Optional attribute to indicate time of last
+ *			    activity. If none is to be specified, the value
+ *			    MUST be set to NULL.
+ * @param content_tp	    Optional attribute to indicate the content type of
+ *			    message being composed. If none is to be specified, 
+ *			    the value MUST be set to NULL.
+ * @param refresh	    Optional attribute to indicate the interval when
+ *			    next indication will be sent, only when 
+ *			    is_composing is non-zero. If none is to be 
+ *			    specified, the value MUST be set to -1.
+ *
+ * @return		    The SIP message body containing XML message 
+ *			    indication. NULL will be returned when there's not
+ *			    enough memory to allocate the message.
+ */
+PJ_DECL(pjsip_msg_body*) pjsip_iscomposing_create_body( pj_pool_t *pool,
+						   pj_bool_t is_composing,
+						   const pj_time_val *lst_actv,
+						   const pj_str_t *content_tp,
+						   int refresh);
+
+
+/**
+ * Parse the buffer and return message composition indication in the 
+ * message.
+ *
+ * @param pool		    Pool to allocate memory for the parsing process.
+ * @param msg		    The message to be parsed.
+ * @param len		    Length of the message.
+ * @param p_is_composing    Optional pointer to receive iscomposing status.
+ * @param p_last_active	    Optional pointer to receive last active attribute.
+ * @param p_content_type    Optional pointer to receive content type attribute.
+ * @param p_refresh	    Optional pointer to receive refresh time.
+ *
+ * @return		    PJ_SUCCESS if message can be successfully parsed.
+ */
+PJ_DECL(pj_status_t) pjsip_iscomposing_parse( pj_pool_t *pool,
+					      char *msg,
+					      pj_size_t len,
+					      pj_bool_t *p_is_composing,
+					      pj_str_t **p_last_active,
+					      pj_str_t **p_content_type,
+					      int *p_refresh );
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif	/* __PJSIP_SIMPLE_ISCOMPOSING_H__ */
+
diff --git a/jni/pjproject-android/.svn/pristine/7d/7dbefefce960d271232e98bd55523cfff864a8f8.svn-base b/jni/pjproject-android/.svn/pristine/7d/7dbefefce960d271232e98bd55523cfff864a8f8.svn-base
new file mode 100644
index 0000000..c189698
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/7d/7dbefefce960d271232e98bd55523cfff864a8f8.svn-base
@@ -0,0 +1,468 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-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-audiodev/audiodev_imp.h>
+#include <pjmedia/sound.h>
+#include <pj/assert.h>
+
+#if PJMEDIA_AUDIO_DEV_HAS_LEGACY_DEVICE
+
+#define THIS_FILE			"legacy_dev.c"
+
+/* Legacy devices factory */
+struct legacy_factory
+{
+    pjmedia_aud_dev_factory	 base;
+    pj_pool_t			*pool;
+    pj_pool_factory		*pf;
+};
+
+
+struct legacy_stream
+{
+    pjmedia_aud_stream	 base;
+
+    pj_pool_t		*pool;
+    pjmedia_aud_param    param;
+    pjmedia_snd_stream	*snd_strm;
+    pjmedia_aud_play_cb	 user_play_cb;
+    pjmedia_aud_rec_cb   user_rec_cb;
+    void		*user_user_data;
+    unsigned		 input_latency;
+    unsigned		 output_latency;
+};
+
+
+/* Prototypes */
+static pj_status_t factory_init(pjmedia_aud_dev_factory *f);
+static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f);
+static unsigned    factory_get_dev_count(pjmedia_aud_dev_factory *f);
+static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, 
+					unsigned index,
+					pjmedia_aud_dev_info *info);
+static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
+					 unsigned index,
+					 pjmedia_aud_param *param);
+static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
+					 const pjmedia_aud_param *param,
+					 pjmedia_aud_rec_cb rec_cb,
+					 pjmedia_aud_play_cb play_cb,
+					 void *user_data,
+					 pjmedia_aud_stream **p_aud_strm);
+
+static pj_status_t stream_get_param(pjmedia_aud_stream *strm,
+				    pjmedia_aud_param *param);
+static pj_status_t stream_get_cap(pjmedia_aud_stream *strm,
+				  pjmedia_aud_dev_cap cap,
+				  void *value);
+static pj_status_t stream_set_cap(pjmedia_aud_stream *strm,
+				  pjmedia_aud_dev_cap cap,
+				  const void *value);
+static pj_status_t stream_start(pjmedia_aud_stream *strm);
+static pj_status_t stream_stop(pjmedia_aud_stream *strm);
+static pj_status_t stream_destroy(pjmedia_aud_stream *strm);
+
+
+/* Operations */
+static pjmedia_aud_dev_factory_op factory_op =
+{
+    &factory_init,
+    &factory_destroy,
+    &factory_get_dev_count,
+    &factory_get_dev_info,
+    &factory_default_param,
+    &factory_create_stream,
+    &factory_refresh
+};
+
+static pjmedia_aud_stream_op stream_op = 
+{
+    &stream_get_param,
+    &stream_get_cap,
+    &stream_set_cap,
+    &stream_start,
+    &stream_stop,
+    &stream_destroy
+};
+
+
+/****************************************************************************
+ * Factory operations
+ */
+
+/*
+ * Init legacy audio driver.
+ */
+pjmedia_aud_dev_factory* pjmedia_legacy_factory(pj_pool_factory *pf)
+{
+    struct legacy_factory *f;
+    pj_pool_t *pool;
+
+    pool = pj_pool_create(pf, "legacy-snd", 512, 512, NULL);
+    f = PJ_POOL_ZALLOC_T(pool, struct legacy_factory);
+    f->pf = pf;
+    f->pool = pool;
+    f->base.op = &factory_op;
+
+    return &f->base;
+}
+
+
+/* API: init factory */
+static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
+{
+    struct legacy_factory *wf = (struct legacy_factory*)f;
+
+    return pjmedia_snd_init(wf->pf);
+}
+
+/* API: destroy factory */
+static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)
+{
+    struct legacy_factory *wf = (struct legacy_factory*)f;
+    pj_status_t status;
+
+    status = pjmedia_snd_deinit();
+
+    if (status == PJ_SUCCESS) {
+	pj_pool_t *pool = wf->pool;
+	wf->pool = NULL;
+	pj_pool_release(pool);
+    }
+
+    return status;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f)
+{
+    PJ_UNUSED_ARG(f);
+    return PJ_ENOTSUP;
+}
+
+/* API: get number of devices */
+static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f)
+{
+    PJ_UNUSED_ARG(f);
+    return pjmedia_snd_get_dev_count();
+}
+
+/* API: get device info */
+static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, 
+					unsigned index,
+					pjmedia_aud_dev_info *info)
+{
+    const pjmedia_snd_dev_info *si = 
+	pjmedia_snd_get_dev_info(index);;
+
+    PJ_UNUSED_ARG(f);
+
+    if (si == NULL)
+	return PJMEDIA_EAUD_INVDEV;
+
+    pj_bzero(info, sizeof(*info));
+    pj_ansi_strncpy(info->name, si->name, sizeof(info->name));
+    info->name[sizeof(info->name)-1] = '\0';
+    info->input_count = si->input_count;
+    info->output_count = si->output_count;
+    info->default_samples_per_sec = si->default_samples_per_sec;
+    pj_ansi_strcpy(info->driver, "legacy");
+    info->caps = PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY | 
+		 PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;
+
+    return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
+					 unsigned index,
+					 pjmedia_aud_param *param)
+{
+    pjmedia_aud_dev_info di;
+    pj_status_t status;
+
+    status = factory_get_dev_info(f, index, &di);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    pj_bzero(param, sizeof(*param));
+    if (di.input_count && di.output_count) {
+	param->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
+	param->rec_id = index;
+	param->play_id = index;
+    } else if (di.input_count) {
+	param->dir = PJMEDIA_DIR_CAPTURE;
+	param->rec_id = index;
+	param->play_id = PJMEDIA_AUD_INVALID_DEV;
+    } else if (di.output_count) {
+	param->dir = PJMEDIA_DIR_PLAYBACK;
+	param->play_id = index;
+	param->rec_id = PJMEDIA_AUD_INVALID_DEV;
+    } else {
+	return PJMEDIA_EAUD_INVDEV;
+    }
+
+    param->clock_rate = di.default_samples_per_sec;
+    param->channel_count = 1;
+    param->samples_per_frame = di.default_samples_per_sec * 20 / 1000;
+    param->bits_per_sample = 16;
+    param->flags = di.caps;
+    param->input_latency_ms = PJMEDIA_SND_DEFAULT_REC_LATENCY;
+    param->output_latency_ms = PJMEDIA_SND_DEFAULT_PLAY_LATENCY;
+
+    return PJ_SUCCESS;
+}
+
+/* Callback from legacy sound device */
+static pj_status_t snd_play_cb(/* in */   void *user_data,
+			       /* in */   pj_uint32_t timestamp,
+			       /* out */  void *output,
+			       /* out */  unsigned size)
+{
+    struct legacy_stream *strm = (struct legacy_stream*)user_data;
+    pjmedia_frame frame;
+    pj_status_t status;
+
+    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+    frame.buf = output;
+    frame.size = size;
+    frame.timestamp.u64 = timestamp;
+
+    status = strm->user_play_cb(strm->user_user_data, &frame);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {
+	pj_bzero(output, size);
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* Callback from legacy sound device */
+static pj_status_t snd_rec_cb( /* in */   void *user_data,
+			       /* in */   pj_uint32_t timestamp,
+			       /* in */   void *input,
+			       /* in*/    unsigned size)
+{
+    struct legacy_stream *strm = (struct legacy_stream*)user_data;
+    pjmedia_frame frame;
+    
+    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+    frame.buf = input;
+    frame.size = size;
+    frame.timestamp.u64 = timestamp;
+
+    return strm->user_rec_cb(strm->user_user_data, &frame);
+}
+
+/* API: create stream */
+static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
+					 const pjmedia_aud_param *param,
+					 pjmedia_aud_rec_cb rec_cb,
+					 pjmedia_aud_play_cb play_cb,
+					 void *user_data,
+					 pjmedia_aud_stream **p_aud_strm)
+{
+    struct legacy_factory *wf = (struct legacy_factory*)f;
+    pj_pool_t *pool;
+    struct legacy_stream *strm;
+    pj_status_t status;
+
+    /* Initialize our stream data */
+    pool = pj_pool_create(wf->pf, "legacy-snd", 512, 512, NULL);
+    strm = PJ_POOL_ZALLOC_T(pool, struct legacy_stream);
+    strm->pool = pool;
+    strm->user_rec_cb = rec_cb;
+    strm->user_play_cb = play_cb;
+    strm->user_user_data = user_data;
+    pj_memcpy(&strm->param, param, sizeof(*param));
+
+    /* Set the latency if wanted */
+    if (param->dir==PJMEDIA_DIR_CAPTURE_PLAYBACK &&
+	param->flags & (PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY |
+			PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY))
+    {
+	PJ_ASSERT_RETURN(param->input_latency_ms &&
+			 param->output_latency_ms,
+			 PJMEDIA_EAUD_BADLATENCY);
+
+	strm->input_latency = param->input_latency_ms;
+	strm->output_latency = param->output_latency_ms;
+
+	status = pjmedia_snd_set_latency(param->input_latency_ms,
+					 param->output_latency_ms);
+	if (status != PJ_SUCCESS) {
+	    pj_pool_release(pool);
+	    return status;
+	}
+    }
+
+    /* Open the stream */
+    if (param->dir == PJMEDIA_DIR_CAPTURE) {
+	status = pjmedia_snd_open_rec(param->rec_id,
+				      param->clock_rate,
+				      param->channel_count,
+				      param->samples_per_frame,
+				      param->bits_per_sample,
+				      &snd_rec_cb,
+				      strm,
+				      &strm->snd_strm);
+    } else if (param->dir == PJMEDIA_DIR_PLAYBACK) {
+	status = pjmedia_snd_open_player(param->play_id,
+					 param->clock_rate,
+					 param->channel_count,
+					 param->samples_per_frame,
+					 param->bits_per_sample,
+					 &snd_play_cb,
+					 strm,
+					 &strm->snd_strm);
+
+    } else if (param->dir == PJMEDIA_DIR_CAPTURE_PLAYBACK) {
+	status = pjmedia_snd_open(param->rec_id,
+				  param->play_id,
+				  param->clock_rate,
+				  param->channel_count,
+				  param->samples_per_frame,
+				  param->bits_per_sample,
+				  &snd_rec_cb,
+				  &snd_play_cb,
+				  strm,
+				  &strm->snd_strm);
+    } else {
+	pj_assert(!"Invalid direction!");
+	return PJ_EINVAL;
+    }
+
+    if (status != PJ_SUCCESS) {
+	pj_pool_release(pool);
+	return status;
+    }
+
+    *p_aud_strm = &strm->base;
+    return PJ_SUCCESS;
+}
+
+/* API: Get stream info. */
+static pj_status_t stream_get_param(pjmedia_aud_stream *s,
+				    pjmedia_aud_param *pi)
+{
+    struct legacy_stream *strm = (struct legacy_stream*)s;
+    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+    pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+    if (strm->input_latency) {
+	pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;
+	pi->input_latency_ms = strm->input_latency;
+    } else {
+	pi->flags &= ~PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;
+    }
+
+    if (strm->output_latency) {
+	pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;
+	pi->output_latency_ms = strm->output_latency;
+    } else {
+	pi->flags &= ~PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t stream_get_cap(pjmedia_aud_stream *s,
+				  pjmedia_aud_dev_cap cap,
+				  void *pval)
+{
+    struct legacy_stream *strm = (struct legacy_stream*)s;
+
+    PJ_ASSERT_RETURN(strm && pval, PJ_EINVAL);
+
+    if (cap==PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY && 
+	(strm->param.dir & PJMEDIA_DIR_CAPTURE)) 
+    {
+	/* Recording latency */
+	if (strm->input_latency) {
+	    *(unsigned*)pval = strm->input_latency;
+	    return PJ_SUCCESS;
+	} else {
+	    return PJMEDIA_EAUD_INVCAP;
+	}
+
+    } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY  && 
+	       (strm->param.dir & PJMEDIA_DIR_PLAYBACK))
+    {
+	/* Playback latency */
+	if (strm->output_latency) {
+	    *(unsigned*)pval = strm->output_latency;
+	    return PJ_SUCCESS;
+	} else {
+	    return PJMEDIA_EAUD_INVCAP;
+	}
+    } else {
+	return PJMEDIA_EAUD_INVCAP;
+    }
+}
+
+/* API: set capability */
+static pj_status_t stream_set_cap(pjmedia_aud_stream *s,
+				  pjmedia_aud_dev_cap cap,
+				  const void *pval)
+{
+    PJ_UNUSED_ARG(s);
+    PJ_UNUSED_ARG(cap);
+    PJ_UNUSED_ARG(pval);
+    return PJMEDIA_EAUD_INVCAP;
+}
+
+/* API: Start stream. */
+static pj_status_t stream_start(pjmedia_aud_stream *s)
+{
+    struct legacy_stream *strm = (struct legacy_stream*)s;
+    return pjmedia_snd_stream_start(strm->snd_strm);
+}
+
+/* API: Stop stream. */
+static pj_status_t stream_stop(pjmedia_aud_stream *s)
+{
+    struct legacy_stream *strm = (struct legacy_stream*)s;
+    return pjmedia_snd_stream_stop(strm->snd_strm);
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t stream_destroy(pjmedia_aud_stream *s)
+{
+    struct legacy_stream *strm = (struct legacy_stream*)s;
+    pj_status_t status;
+
+    status = pjmedia_snd_stream_close(strm->snd_strm);
+
+    if (status == PJ_SUCCESS) {
+	pj_pool_t *pool = strm->pool;
+
+	strm->pool = NULL;
+	pj_pool_release(pool);
+    }
+
+    return status;
+}
+
+#endif	/* PJMEDIA_AUDIO_DEV_HAS_LEGACY_DEVICE */
+