* #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/2d/2d036492ea1e1f1540d40da8e3586ed8c2d32ed6.svn-base b/jni/pjproject-android/.svn/pristine/2d/2d036492ea1e1f1540d40da8e3586ed8c2d32ed6.svn-base
new file mode 100644
index 0000000..f4c5dac
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2d036492ea1e1f1540d40da8e3586ed8c2d32ed6.svn-base
@@ -0,0 +1,19 @@
+# $Id$
+#
+from inc_cfg import *
+
+ADD_PARAM = ""
+
+if (HAS_SND_DEV == 0):
+	ADD_PARAM += "--null-audio"
+
+# Call with Speex/16000 codec
+test_param = TestParam(
+		"PESQ codec Speex WB",
+		[
+			InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --clock-rate 16000 --add-codec speex/16000 --play-file wavs/input.16.wav --no-vad"),
+			InstanceParam("UA2", "--null-audio --max-calls=1 --clock-rate 16000 --add-codec speex/16000 --rec-file  wavs/tmp.16.wav --auto-answer 200")
+		]
+		)
+
+pesq_threshold = 3.8
diff --git a/jni/pjproject-android/.svn/pristine/2d/2d306888182175955e11dc0380eeaae20a303801.svn-base b/jni/pjproject-android/.svn/pristine/2d/2d306888182175955e11dc0380eeaae20a303801.svn-base
new file mode 100644
index 0000000..a3be41b
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2d306888182175955e11dc0380eeaae20a303801.svn-base
@@ -0,0 +1,335 @@
+/* $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 
+ */
+#import "RootViewController.h"
+#import "gui.h"
+#import "systest.h"
+
+/* Sleep interval duration, change to shorter duration for better
+ * interaction but make sure there is enough time for the other
+ * thread to do what it's supposed to do
+ */
+#define SLEEP_INTERVAL 0.5
+
+@implementation RootViewController
+@synthesize titles;
+@synthesize menus;
+@synthesize testView;
+
+RootViewController	*view;
+
+bool			systest_initialized;
+bool			thread_quit;
+gui_menu		*gmenu;
+int			section;
+int			row;
+const char		*ctitle;
+const char		*cmsg; 
+enum gui_flag		cflag;
+
+pj_status_t gui_init(gui_menu *menu)
+{
+    PJ_UNUSED_ARG(menu);
+    return PJ_SUCCESS;
+}
+
+/* Run GUI main loop */
+pj_status_t gui_start(gui_menu *menu)
+{
+    view.titles = [NSMutableArray arrayWithCapacity:menu->submenu_cnt];
+    view.menus = [NSMutableArray arrayWithCapacity:menu->submenu_cnt];
+    NSMutableArray *smenu;
+    for (int i = 0; i < menu->submenu_cnt; i++) {
+	NSString *str = [NSString stringWithFormat:@"%s" , menu->submenus[i]->title];
+	[view.titles addObject: str];
+	smenu = [NSMutableArray arrayWithCapacity:menu->submenus[i]->submenu_cnt];
+	/* We do not need the last two menus of the "Tests" menu (NULL and "Exit"),
+	 * so subtract by 2
+	 */
+	for (int j = 0; j < menu->submenus[i]->submenu_cnt - (i==0? 2: 0); j++) {
+	    str = [NSString stringWithFormat:@"%s" , menu->submenus[i]->submenus[j]->title];
+	    [smenu addObject:str];
+	}
+	[view.menus addObject:smenu];
+    }
+    gmenu = menu;
+    
+    return PJ_SUCCESS;
+}
+
+/* Signal GUI mainloop to stop */
+void gui_destroy(void)
+{
+}
+
+/* AUX: display messagebox */
+enum gui_key gui_msgbox(const char *title, const char *message, enum gui_flag flag)
+{
+    ctitle = title;
+    cmsg = message;
+    cflag = flag;
+    [view performSelectorOnMainThread:@selector(showMsg) withObject:nil waitUntilDone:YES];
+    
+    view.testView.key = 0;
+    while(view.testView.key == 0) {
+	/* Let the main thread do its job (refresh the view) while we wait for 
+	 * user interaction (button click)
+	 */
+	[NSThread sleepForTimeInterval:SLEEP_INTERVAL];
+    }
+    
+    if (view.testView.key == 1)
+	return KEY_OK;
+    else
+	return (flag == WITH_YESNO? KEY_NO: KEY_CANCEL);
+}
+
+/* AUX: sleep */
+void gui_sleep(unsigned sec)
+{
+    [NSThread sleepForTimeInterval:sec];
+}
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    view = self;
+    
+    /* Get a writable path for output files */
+    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+    NSString *documentsDirectory = [paths objectAtIndex:0];
+    [documentsDirectory getCString:doc_path maxLength:PATH_LENGTH encoding:NSASCIIStringEncoding];
+    strncat(doc_path, "/", PATH_LENGTH);
+
+    /* Get path for our test resources (the wav files) */
+    NSString *resPath = [[NSBundle mainBundle] resourcePath];
+    [resPath getCString:res_path maxLength:PATH_LENGTH encoding:NSASCIIStringEncoding];
+    strncat(res_path, "/", PATH_LENGTH);
+    
+    systest_initialized = false;
+    thread_quit = false;
+    [NSThread detachNewThreadSelector:@selector(startTest) toTarget:self withObject:nil];
+    /* Let our new thread initialize */
+    while (!systest_initialized) {
+	[NSThread sleepForTimeInterval:SLEEP_INTERVAL];
+    }
+
+    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
+    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
+}
+
+/*
+ - (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+ }
+ */
+/*
+ - (void)viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+ }
+ */
+/*
+ - (void)viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+ }
+ */
+/*
+ - (void)viewDidDisappear:(BOOL)animated {
+    [super viewDidDisappear:animated];
+ }
+ */
+
+/*
+ // Override to allow orientations other than the default portrait orientation.
+ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+    // Return YES for supported orientations.
+    return (interfaceOrientation == UIInterfaceOrientationPortrait);
+ }
+ */
+
+- (void)didReceiveMemoryWarning {
+    // Releases the view if it doesn't have a superview.
+    [super didReceiveMemoryWarning];
+    
+    // Release any cached data, images, etc that aren't in use.
+}
+
+- (void)viewDidUnload {
+    // Release anything that can be recreated in viewDidLoad or on demand.
+    // e.g. self.myOutlet = nil;
+    self.titles = nil;
+    self.menus = nil;
+    
+    thread_quit = true;
+    [NSThread sleepForTimeInterval:SLEEP_INTERVAL];
+}
+
+
+#pragma mark Table view methods
+
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    return [titles count];
+}
+
+
+// Customize the number of rows in the table view.
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return [[menus objectAtIndex:section] count];
+}
+
+
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
+    // The header for the section is the region name -- get this from the region at the section index.
+    return [titles objectAtIndex:section];
+}
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+    static NSString *CellIdentifier = @"Cell";
+    
+    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+    if (cell == nil) {
+        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+    }
+    
+    // Configure the cell.
+    cell.textLabel.text = [[menus objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
+    
+    return cell;
+}
+
+- (void)startTest {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    if (systest_init() != PJ_SUCCESS) {
+	[pool release];
+	return;
+    }
+    
+    systest_run();
+    
+    systest_initialized = 1;
+    while(!thread_quit) {
+	section = -1;
+	while (section == -1) {
+	    [NSThread sleepForTimeInterval:SLEEP_INTERVAL];
+	}
+	(*gmenu->submenus[section]->submenus[row]->handler)();
+	cmsg = NULL;
+	[view performSelectorOnMainThread:@selector(showMsg) withObject:nil waitUntilDone:YES];
+    }
+    
+    systest_deinit();
+    [pool release];
+}
+
+- (void)showMsg {
+    if (cmsg == NULL) {
+	self.testView.testDesc.text = [self.testView.testDesc.text stringByAppendingString: @"Finished"];
+	[self.testView.testDesc scrollRangeToVisible:NSMakeRange([self.testView.testDesc.text length] - 1, 1)];
+	[self.testView.button1 setHidden:true];
+	[self.testView.button2 setHidden:true];
+	return;
+    }
+    self.testView.title = [NSString stringWithFormat:@"%s", ctitle];
+    self.testView.testDesc.text = [self.testView.testDesc.text stringByAppendingString: [NSString stringWithFormat:@"%s\n\n", cmsg]];
+    [self.testView.testDesc scrollRangeToVisible:NSMakeRange([self.testView.testDesc.text length] - 1, 1)];
+    
+    [self.testView.button1 setHidden:false];
+    [self.testView.button2 setHidden:false];
+    if (cflag == WITH_YESNO) {
+	[self.testView.button1 setTitle:@"Yes" forState:UIControlStateNormal];
+	[self.testView.button2 setTitle:@"No" forState:UIControlStateNormal];
+    } else if (cflag == WITH_OK) {
+	[self.testView.button1 setTitle:@"OK" forState:UIControlStateNormal];
+	[self.testView.button2 setHidden:true];
+    } else if (cflag == WITH_OKCANCEL) {
+	[self.testView.button1 setTitle:@"OK" forState:UIControlStateNormal];
+	[self.testView.button2 setTitle:@"Cancel" forState:UIControlStateNormal];
+    }
+}
+
+
+// Override to support row selection in the table view.
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+    // Navigation logic may go here -- for example, create and push another view controller.
+    // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
+    // [self.navigationController pushViewController:anotherViewController animated:YES];
+    // [anotherViewController release];
+    
+    if (self.testView == nil) {
+	self.testView = [[TestViewController alloc] initWithNibName:@"TestViewController" bundle:[NSBundle mainBundle]];
+    }
+    
+    [self.navigationController pushViewController:self.testView animated:YES];
+    self.testView.title = [[menus objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
+    self.testView.testDesc.text = @"";
+    section = indexPath.section;
+    row = indexPath.row;
+}
+
+
+/*
+ // Override to support conditional editing of the table view.
+ - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
+    // Return NO if you do not want the specified item to be editable.
+    return YES;
+ }
+ */
+
+
+/*
+ // Override to support editing the table view.
+ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+ 
+    if (editingStyle == UITableViewCellEditingStyleDelete) {
+	// Delete the row from the data source.
+	[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
+    }   
+    else if (editingStyle == UITableViewCellEditingStyleInsert) {
+	// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
+    }   
+ }
+ */
+
+
+/*
+ // Override to support rearranging the table view.
+ - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
+ }
+ */
+
+
+/*
+ // Override to support conditional rearranging of the table view.
+ - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
+    // Return NO if you do not want the item to be re-orderable.
+    return YES;
+ }
+ */
+
+
+- (void)dealloc {
+    [super dealloc];
+}
+
+
+@end
+
diff --git a/jni/pjproject-android/.svn/pristine/2d/2d3bbb2e0d43c9b4598500e71b3ea71989b9d352.svn-base b/jni/pjproject-android/.svn/pristine/2d/2d3bbb2e0d43c9b4598500e71b3ea71989b9d352.svn-base
new file mode 100644
index 0000000..9db31a1
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2d3bbb2e0d43c9b4598500e71b3ea71989b9d352.svn-base
@@ -0,0 +1,9 @@
+export OS_CFLAGS   := $(CC_DEF)PJ_DARWINOS=1
+
+export OS_CXXFLAGS := 
+
+export OS_LDFLAGS  := $(CC_LIB)pthread$(LIBEXT2) -framework CoreAudio -lm
+
+export OS_SOURCES  := 
+
+
diff --git a/jni/pjproject-android/.svn/pristine/2d/2d4706de6452e2b1bcb9d06a1d1a6a61d2a77d21.svn-base b/jni/pjproject-android/.svn/pristine/2d/2d4706de6452e2b1bcb9d06a1d1a6a61d2a77d21.svn-base
new file mode 100644
index 0000000..c58ca26
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2d4706de6452e2b1bcb9d06a1d1a6a61d2a77d21.svn-base
@@ -0,0 +1,516 @@
+/* $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"
+#include "server.h"
+
+#define SRV_DOMAIN	"pjsip.lab.domain"
+#define KA_INTERVAL	50
+
+struct test_result
+{
+    unsigned    state_called;
+    unsigned    rx_data_cnt;
+};
+
+struct test_session
+{
+    pj_pool_t		*pool;
+    pj_stun_config	*stun_cfg;
+    pj_turn_sock	*turn_sock;
+    pj_dns_resolver	*resolver;
+    test_server		*test_srv;
+
+    pj_bool_t		 destroy_called;
+    int			 destroy_on_state;
+    struct test_result	 result;
+};
+
+struct test_session_cfg
+{
+    struct {
+	pj_bool_t	enable_dns_srv;
+	int		destroy_on_state;
+    } client;
+
+    struct {
+	pj_uint32_t	flags;
+	pj_bool_t	respond_allocate;
+	pj_bool_t	respond_refresh;
+    } srv;
+};
+
+static void turn_on_rx_data(pj_turn_sock *turn_sock,
+			    void *pkt,
+			    unsigned pkt_len,
+			    const pj_sockaddr_t *peer_addr,
+			    unsigned addr_len);
+static void turn_on_state(pj_turn_sock *turn_sock, 
+			  pj_turn_state_t old_state,
+			  pj_turn_state_t new_state);
+
+static void destroy_session(struct test_session *sess)
+{
+    if (sess->resolver) {
+	pj_dns_resolver_destroy(sess->resolver, PJ_TRUE);
+	sess->resolver = NULL;
+    }
+
+    if (sess->turn_sock) {
+	if (!sess->destroy_called) {
+	    sess->destroy_called = PJ_TRUE;
+	    pj_turn_sock_destroy(sess->turn_sock);
+	}
+	sess->turn_sock = NULL;
+    }
+
+    if (sess->test_srv) {
+	destroy_test_server(sess->test_srv);
+	sess->test_srv = NULL;
+    }
+
+    if (sess->pool) {
+	pj_pool_release(sess->pool);
+    }
+}
+
+
+
+static int create_test_session(pj_stun_config  *stun_cfg,
+			       const struct test_session_cfg *cfg,
+			       struct test_session **p_sess)
+{
+    struct test_session *sess;
+    pj_pool_t *pool;
+    pj_turn_sock_cb turn_sock_cb;
+    pj_turn_alloc_param alloc_param;
+    pj_stun_auth_cred cred;
+    pj_status_t status;
+
+    /* Create client */
+    pool = pj_pool_create(mem, "turnclient", 512, 512, NULL);
+    sess = PJ_POOL_ZALLOC_T(pool, struct test_session);
+    sess->pool = pool;
+    sess->stun_cfg = stun_cfg;
+    sess->destroy_on_state = cfg->client.destroy_on_state;
+
+    pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb));
+    turn_sock_cb.on_rx_data = &turn_on_rx_data;
+    turn_sock_cb.on_state = &turn_on_state;
+    status = pj_turn_sock_create(sess->stun_cfg, pj_AF_INET(), PJ_TURN_TP_UDP,
+				 &turn_sock_cb, 0, sess, &sess->turn_sock);
+    if (status != PJ_SUCCESS) {
+	destroy_session(sess);
+	return -20;
+    }
+
+    /* Create test server */
+    status = create_test_server(sess->stun_cfg, cfg->srv.flags,
+				SRV_DOMAIN, &sess->test_srv);
+    if (status != PJ_SUCCESS) {
+	destroy_session(sess);
+	return -30;
+    }
+
+    sess->test_srv->turn_respond_allocate = cfg->srv.respond_allocate;
+    sess->test_srv->turn_respond_refresh = cfg->srv.respond_refresh;
+
+    /* Create client resolver */
+    status = pj_dns_resolver_create(mem, "resolver", 0, sess->stun_cfg->timer_heap,
+				    sess->stun_cfg->ioqueue, &sess->resolver);
+    if (status != PJ_SUCCESS) {
+	destroy_session(sess);
+	return -40;
+
+    } else {
+	pj_str_t dns_srv = pj_str("127.0.0.1");
+	pj_uint16_t dns_srv_port = (pj_uint16_t) DNS_SERVER_PORT;
+	status = pj_dns_resolver_set_ns(sess->resolver, 1, &dns_srv, &dns_srv_port);
+
+	if (status != PJ_SUCCESS) {
+	    destroy_session(sess);
+	    return -50;
+	}
+    }
+
+    /* Init TURN credential */
+    pj_bzero(&cred, sizeof(cred));
+    cred.type = PJ_STUN_AUTH_CRED_STATIC;
+    cred.data.static_cred.realm = pj_str(SRV_DOMAIN);
+    cred.data.static_cred.username = pj_str(TURN_USERNAME);
+    cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
+    cred.data.static_cred.data = pj_str(TURN_PASSWD);
+
+    /* Init TURN allocate parameter */
+    pj_turn_alloc_param_default(&alloc_param);
+    alloc_param.ka_interval = KA_INTERVAL;
+
+    /* Start the client */
+    if (cfg->client.enable_dns_srv) {
+	/* Use DNS SRV to resolve server, may fallback to DNS A */
+	pj_str_t domain = pj_str(SRV_DOMAIN);
+	status = pj_turn_sock_alloc(sess->turn_sock, &domain, TURN_SERVER_PORT,
+				    sess->resolver, &cred, &alloc_param);
+
+    } else {
+	/* Explicitly specify server address */
+	pj_str_t host = pj_str("127.0.0.1");
+	status = pj_turn_sock_alloc(sess->turn_sock, &host, TURN_SERVER_PORT,
+				    NULL, &cred, &alloc_param);
+
+    }
+
+    if (status != PJ_SUCCESS) {
+	if (cfg->client.destroy_on_state >= PJ_TURN_STATE_READY) {
+	    destroy_session(sess);
+	    return -70;
+	}
+    }
+
+    *p_sess = sess;
+    return 0;
+}
+
+
+static void turn_on_rx_data(pj_turn_sock *turn_sock,
+			    void *pkt,
+			    unsigned pkt_len,
+			    const pj_sockaddr_t *peer_addr,
+			    unsigned addr_len)
+{
+    struct test_session *sess;
+
+    PJ_UNUSED_ARG(pkt);
+    PJ_UNUSED_ARG(pkt_len);
+    PJ_UNUSED_ARG(peer_addr);
+    PJ_UNUSED_ARG(addr_len);
+
+    sess = (struct test_session*) pj_turn_sock_get_user_data(turn_sock);
+    if (sess == NULL)
+	return;
+
+    sess->result.rx_data_cnt++;
+}
+
+
+static void turn_on_state(pj_turn_sock *turn_sock, 
+			  pj_turn_state_t old_state,
+			  pj_turn_state_t new_state)
+{
+    struct test_session *sess;
+    unsigned i, mask;
+
+    PJ_UNUSED_ARG(old_state);
+
+    sess = (struct test_session*) pj_turn_sock_get_user_data(turn_sock);
+    if (sess == NULL)
+	return;
+
+    /* This state must not be called before */
+    pj_assert((sess->result.state_called & (1<<new_state)) == 0);
+
+    /* new_state must be greater than old_state */
+    pj_assert(new_state > old_state);
+
+    /* must not call any greater state before */
+    mask = 0;
+    for (i=new_state+1; i<31; ++i) mask |= (1 << i);
+
+    pj_assert((sess->result.state_called & mask) == 0);
+
+    sess->result.state_called |= (1 << new_state);
+
+    if (new_state >= sess->destroy_on_state && !sess->destroy_called) {
+	sess->destroy_called = PJ_TRUE;
+	pj_turn_sock_destroy(turn_sock);
+    }
+
+    if (new_state >= PJ_TURN_STATE_DESTROYING) {
+	pj_turn_sock_set_user_data(sess->turn_sock, NULL);
+	sess->turn_sock = NULL;
+    }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+static int state_progression_test(pj_stun_config  *stun_cfg)
+{
+    struct test_session_cfg test_cfg = 
+    {
+	{   /* Client cfg */
+	    /* DNS SRV */   /* Destroy on state */
+	    PJ_TRUE,	    0xFFFF
+	},
+	{   /* Server cfg */
+	    0xFFFFFFFF,	    /* flags */
+	    PJ_TRUE,	    /* respond to allocate  */
+	    PJ_TRUE	    /* respond to refresh   */
+	}
+    };
+    struct test_session *sess;
+    unsigned i;
+    int rc;
+
+    PJ_LOG(3,("", "  state progression tests"));
+
+    for (i=0; i<=1; ++i) {
+	enum { TIMEOUT = 60 };
+	pjlib_state pjlib_state;
+	pj_turn_session_info info;
+	struct test_result result;
+	pj_time_val tstart;
+
+	PJ_LOG(3,("", "   %s DNS SRV resolution",
+	              (i==0? "without" : "with")));
+
+	capture_pjlib_state(stun_cfg, &pjlib_state);
+
+	test_cfg.client.enable_dns_srv = i;
+
+	rc = create_test_session(stun_cfg, &test_cfg, &sess);
+	if (rc != 0)
+	    return rc;
+
+	pj_bzero(&info, sizeof(info));
+
+	/* Wait until state is READY */
+	pj_gettimeofday(&tstart);
+	while (sess->turn_sock) {
+	    pj_time_val now;
+
+	    poll_events(stun_cfg, 10, PJ_FALSE);
+	    rc = pj_turn_sock_get_info(sess->turn_sock, &info);
+	    if (rc!=PJ_SUCCESS)
+		break;
+
+	    if (info.state >= PJ_TURN_STATE_READY)
+		break;
+
+	    pj_gettimeofday(&now);
+	    if (now.sec - tstart.sec > TIMEOUT) {
+		PJ_LOG(3,("", "    timed-out"));
+		break;
+	    }
+	}
+
+	if (info.state != PJ_TURN_STATE_READY) {
+	    PJ_LOG(3,("", "    error: state is not READY"));
+	    destroy_session(sess);
+	    return -130;
+	}
+
+	/* Deallocate */
+	pj_turn_sock_destroy(sess->turn_sock);
+
+	/* Wait for couple of seconds.
+	 * We can't poll the session info since the session may have
+	 * been destroyed
+	 */
+	poll_events(stun_cfg, 2000, PJ_FALSE);
+	sess->turn_sock = NULL;
+	pj_memcpy(&result, &sess->result, sizeof(result));
+	destroy_session(sess);
+
+	/* Check the result */
+	if ((result.state_called & (1<<PJ_TURN_STATE_RESOLVING)) == 0) {
+	    PJ_LOG(3,("", "    error: PJ_TURN_STATE_RESOLVING is not called"));
+	    return -140;
+	}
+
+	if ((result.state_called & (1<<PJ_TURN_STATE_RESOLVED)) == 0) {
+	    PJ_LOG(3,("", "    error: PJ_TURN_STATE_RESOLVED is not called"));
+	    return -150;
+	}
+
+	if ((result.state_called & (1<<PJ_TURN_STATE_ALLOCATING)) == 0) {
+	    PJ_LOG(3,("", "    error: PJ_TURN_STATE_ALLOCATING is not called"));
+	    return -155;
+	}
+
+	if ((result.state_called & (1<<PJ_TURN_STATE_READY)) == 0) {
+	    PJ_LOG(3,("", "    error: PJ_TURN_STATE_READY is not called"));
+	    return -160;
+	}
+
+	if ((result.state_called & (1<<PJ_TURN_STATE_DEALLOCATING)) == 0) {
+	    PJ_LOG(3,("", "    error: PJ_TURN_STATE_DEALLOCATING is not called"));
+	    return -170;
+	}
+
+	if ((result.state_called & (1<<PJ_TURN_STATE_DEALLOCATED)) == 0) {
+	    PJ_LOG(3,("", "    error: PJ_TURN_STATE_DEALLOCATED is not called"));
+	    return -180;
+	}
+
+	if ((result.state_called & (1<<PJ_TURN_STATE_DESTROYING)) == 0) {
+	    PJ_LOG(3,("", "    error: PJ_TURN_STATE_DESTROYING is not called"));
+	    return -190;
+	}
+
+	poll_events(stun_cfg, 500, PJ_FALSE);
+	rc = check_pjlib_state(stun_cfg, &pjlib_state);
+	if (rc != 0) {
+	    PJ_LOG(3,("", "    error: memory/timer-heap leak detected"));
+	    return rc;
+	}
+    }
+
+    return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+static int destroy_test(pj_stun_config  *stun_cfg,
+			pj_bool_t with_dns_srv,
+			pj_bool_t in_callback)
+{
+    struct test_session_cfg test_cfg = 
+    {
+	{   /* Client cfg */
+	    /* DNS SRV */   /* Destroy on state */
+	    PJ_TRUE,	    0xFFFF
+	},
+	{   /* Server cfg */
+	    0xFFFFFFFF,	    /* flags */
+	    PJ_TRUE,	    /* respond to allocate  */
+	    PJ_TRUE	    /* respond to refresh   */
+	}
+    };
+    struct test_session *sess;
+    int target_state;
+    int rc;
+
+    PJ_LOG(3,("", "  destroy test %s %s",
+	          (in_callback? "in callback" : ""),
+		  (with_dns_srv? "with DNS srv" : "")
+		  ));
+
+    test_cfg.client.enable_dns_srv = with_dns_srv;
+
+    for (target_state=PJ_TURN_STATE_RESOLVING; target_state<=PJ_TURN_STATE_READY; ++target_state) {
+	enum { TIMEOUT = 60 };
+	pjlib_state pjlib_state;
+	pj_turn_session_info info;
+	pj_time_val tstart;
+
+	capture_pjlib_state(stun_cfg, &pjlib_state);
+
+	PJ_LOG(3,("", "   %s", pj_turn_state_name((pj_turn_state_t)target_state)));
+
+	if (in_callback)
+	    test_cfg.client.destroy_on_state = target_state;
+
+	rc = create_test_session(stun_cfg, &test_cfg, &sess);
+	if (rc != 0)
+	    return rc;
+
+	if (in_callback) {
+	    pj_gettimeofday(&tstart);
+	    rc = 0;
+	    while (sess->turn_sock) {
+		pj_time_val now;
+
+		poll_events(stun_cfg, 100, PJ_FALSE);
+
+		pj_gettimeofday(&now);
+		if (now.sec - tstart.sec > TIMEOUT) {
+		    rc = -7;
+		    break;
+		}
+	    }
+
+	} else {
+	    pj_gettimeofday(&tstart);
+	    rc = 0;
+	    while (sess->turn_sock) {
+		pj_time_val now;
+
+		poll_events(stun_cfg, 1, PJ_FALSE);
+
+		pj_turn_sock_get_info(sess->turn_sock, &info);
+		
+		if (info.state >= target_state) {
+		    pj_turn_sock_destroy(sess->turn_sock);
+		    break;
+		}
+
+		pj_gettimeofday(&now);
+		if (now.sec - tstart.sec > TIMEOUT) {
+		    rc = -8;
+		    break;
+		}
+	    }
+	}
+
+
+	if (rc != 0) {
+	    PJ_LOG(3,("", "    error: timeout"));
+	    return rc;
+	}
+
+	poll_events(stun_cfg, 1000, PJ_FALSE);
+	destroy_session(sess);
+
+	rc = check_pjlib_state(stun_cfg, &pjlib_state);
+	if (rc != 0) {
+	    PJ_LOG(3,("", "    error: memory/timer-heap leak detected"));
+	    return rc;
+	}
+    }
+
+    return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+int turn_sock_test(void)
+{
+    pj_pool_t *pool;
+    pj_stun_config stun_cfg;
+    int i, rc = 0;
+
+    pool = pj_pool_create(mem, "turntest", 512, 512, NULL);
+    rc = create_stun_config(pool, &stun_cfg);
+    if (rc != PJ_SUCCESS) {
+	pj_pool_release(pool);
+	return -2;
+    }
+
+    rc = state_progression_test(&stun_cfg);
+    if (rc != 0) 
+	goto on_return;
+
+    for (i=0; i<=1; ++i) {
+	int j;
+	for (j=0; j<=1; ++j) {
+	    rc = destroy_test(&stun_cfg, i, j);
+	    if (rc != 0)
+		goto on_return;
+	}
+    }
+
+on_return:
+    destroy_stun_config(&stun_cfg);
+    pj_pool_release(pool);
+    return rc;
+}
+
diff --git a/jni/pjproject-android/.svn/pristine/2d/2d7ab882630963151e65998a29b64a16a877e160.svn-base b/jni/pjproject-android/.svn/pristine/2d/2d7ab882630963151e65998a29b64a16a877e160.svn-base
new file mode 100644
index 0000000..44c132f
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2d7ab882630963151e65998a29b64a16a877e160.svn-base
@@ -0,0 +1,146 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <speex/speex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <speex/speex_callbacks.h>
+
+#ifdef FIXED_DEBUG
+extern long long spx_mips;
+#endif
+
+#define FRAME_SIZE 160
+#include <math.h>
+int main(int argc, char **argv)
+{
+   char *inFile, *outFile, *bitsFile;
+   FILE *fin, *fout, *fbits=NULL;
+   short in_short[FRAME_SIZE];
+   short out_short[FRAME_SIZE];
+   int snr_frames = 0;
+   char cbits[200];
+   int nbBits;
+   int i;
+   void *st;
+   void *dec;
+   SpeexBits bits;
+   spx_int32_t tmp;
+   int bitCount=0;
+   spx_int32_t skip_group_delay;
+   SpeexCallback callback;
+
+   st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
+   dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
+
+   /* BEGIN: You probably don't need the following in a real application */
+   callback.callback_id = SPEEX_INBAND_CHAR;
+   callback.func = speex_std_char_handler;
+   callback.data = stderr;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
+   callback.func = speex_std_mode_request_handler;
+   callback.data = st;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+   /* END of unnecessary stuff */
+
+   tmp=1;
+   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
+   tmp=0;
+   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
+   tmp=8;
+   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
+   tmp=1;
+   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
+
+   /* Turn this off if you want to measure SNR (on by default) */
+   tmp=1;
+   speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &tmp);
+   speex_decoder_ctl(dec, SPEEX_SET_HIGHPASS, &tmp);
+
+   speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);
+   speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);
+   skip_group_delay += tmp;
+
+   if (argc != 4 && argc != 3)
+   {
+      fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
+      exit(1);
+   }
+   inFile = argv[1];
+   fin = fopen(inFile, "rb");
+   outFile = argv[2];
+   fout = fopen(outFile, "wb+");
+   if (argc==4)
+   {
+      bitsFile = argv[3];
+      fbits = fopen(bitsFile, "wb");
+   }
+   speex_bits_init(&bits);
+   while (!feof(fin))
+   {
+      fread(in_short, sizeof(short), FRAME_SIZE, fin);
+      if (feof(fin))
+         break;
+      speex_bits_reset(&bits);
+
+      speex_encode_int(st, in_short, &bits);
+      nbBits = speex_bits_write(&bits, cbits, 200);
+      bitCount+=bits.nbBits;
+
+      if (argc==4)
+         fwrite(cbits, 1, nbBits, fbits);
+      speex_bits_rewind(&bits);
+
+      speex_decode_int(dec, &bits, out_short);
+      speex_bits_reset(&bits);
+
+      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
+      skip_group_delay = 0;
+   }
+   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
+   speex_encoder_destroy(st);
+   speex_decoder_destroy(dec);
+   speex_bits_destroy(&bits);
+
+#ifndef DISABLE_FLOAT_API
+   {
+   float sigpow,errpow,snr, seg_snr=0;
+   sigpow = 0;
+   errpow = 0;
+
+   /* This code just computes SNR, so you don't need it either */
+   rewind(fin);
+   rewind(fout);
+
+   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) 
+           &&
+           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )
+   {
+	float s=0, e=0;
+        for (i=0;i<FRAME_SIZE;++i) {
+            s += (float)in_short[i] * in_short[i];
+            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
+        }
+	seg_snr += 10*log10((s+160)/(e+160));
+	sigpow += s;
+	errpow += e;
+	snr_frames++;
+   }
+   snr = 10 * log10( sigpow / errpow );
+   seg_snr /= snr_frames;
+   fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
+
+#ifdef FIXED_DEBUG
+   printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
+#endif
+   }
+#endif
+
+   fclose(fin);
+   fclose(fout);
+
+   return 0;
+}
diff --git a/jni/pjproject-android/.svn/pristine/2d/2d963f55a41e937e50f9de833578933eb93a0d05.svn-base b/jni/pjproject-android/.svn/pristine/2d/2d963f55a41e937e50f9de833578933eb93a0d05.svn-base
new file mode 100644
index 0000000..c81d715
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2d963f55a41e937e50f9de833578933eb93a0d05.svn-base
@@ -0,0 +1,32 @@
+#ifndef __RESAMPLESUBS_H__
+#define __RESAMPLESUBS_H__
+
+typedef char           RES_BOOL;
+typedef short          RES_HWORD;
+typedef int            RES_WORD;
+typedef unsigned short RES_UHWORD;
+typedef unsigned int   RES_UWORD;
+
+#ifdef _USRDLL
+#   define DECL(T)  __declspec(dllexport) T
+#else
+#   define DECL(T)  T
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+DECL(int) res_SrcLinear(const RES_HWORD X[], RES_HWORD Y[], 
+		        double pFactor, RES_UHWORD nx);
+DECL(int) res_Resample(const RES_HWORD X[], RES_HWORD Y[], double pFactor, 
+		       RES_UHWORD nx, RES_BOOL LargeF, RES_BOOL Interp);
+DECL(int) res_GetXOFF(double pFactor, RES_BOOL LargeF);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/jni/pjproject-android/.svn/pristine/2d/2d98db95d9974ed2787ab74c855599112b22f504.svn-base b/jni/pjproject-android/.svn/pristine/2d/2d98db95d9974ed2787ab74c855599112b22f504.svn-base
new file mode 100644
index 0000000..5ea6e79
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2d98db95d9974ed2787ab74c855599112b22f504.svn-base
@@ -0,0 +1,169 @@
+export PJDIR := @ac_pjdir@
+include $(PJDIR)/version.mak
+export PJ_DIR := $(PJDIR)
+
+# @configure_input@
+export MACHINE_NAME := auto
+export OS_NAME := auto
+export HOST_NAME := unix
+export CC_NAME := gcc
+export TARGET_NAME := @target@
+export CROSS_COMPILE := @ac_cross_compile@
+export LINUX_POLL := @ac_linux_poll@ 
+export SHLIB_SUFFIX := @ac_shlib_suffix@
+
+export ac_prefix := @prefix@
+
+LIB_SUFFIX = $(TARGET_NAME).a
+
+# Determine which party libraries to use
+export APP_THIRD_PARTY_LIBS := -lmilenage-$(TARGET_NAME) -lsrtp-$(TARGET_NAME)
+export APP_THIRD_PARTY_EXT :=
+export APP_THIRD_PARTY_LIB_FILES := $(PJ_DIR)/third_party/lib/libmilenage-$(LIB_SUFFIX) $(PJ_DIR)/third_party/lib/libsrtp-$(LIB_SUFFIX)
+
+ifeq (@ac_resample_dll@,1)
+export PJ_RESAMPLE_DLL := 1
+export APP_THIRD_PARTY_LIBS := -lresample $(APP_THIRD_PARTY_LIBS)
+export APP_THIRD_PARTY_LIB_FILES := $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFIX) $(APP_THIRD_PARTY_LIB_FILES)
+else
+export APP_THIRD_PARTY_LIBS := -lresample-$(TARGET_NAME) $(APP_THIRD_PARTY_LIBS)
+export APP_THIRD_PARTY_LIB_FILES := $(PJ_DIR)/third_party/lib/libresample-$(LIB_SUFFIX) $(APP_THIRD_PARTY_LIB_FILES)
+endif
+
+ifneq (@ac_no_gsm_codec@,1)
+ifeq (@ac_external_gsm@,1)
+# External GSM library
+APP_THIRD_PARTY_EXT += -lgsm
+else
+APP_THIRD_PARTY_LIBS += -lgsmcodec-$(TARGET_NAME)
+APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libgsmcodec-$(LIB_SUFFIX)
+endif
+endif
+
+ifneq (@ac_no_speex_codec@,1)
+ifeq (@ac_external_speex@,1)
+APP_THIRD_PARTY_EXT += -lspeex -lspeexdsp
+else
+APP_THIRD_PARTY_LIBS += -lspeex-$(TARGET_NAME)
+APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libspeex-$(LIB_SUFFIX)
+endif
+endif
+
+ifneq (@ac_no_ilbc_codec@,1)
+APP_THIRD_PARTY_LIBS += -lilbccodec-$(TARGET_NAME)
+APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libilbccodec-$(LIB_SUFFIX)
+endif
+
+ifneq (@ac_no_g7221_codec@,1)
+APP_THIRD_PARTY_LIBS += -lg7221codec-$(TARGET_NAME)
+APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libg7221codec-$(LIB_SUFFIX)
+endif
+
+ifneq ($(findstring pa,@ac_pjmedia_snd@),)
+ifeq (@ac_external_pa@,1)
+# External PA
+APP_THIRD_PARTY_EXT += -lportaudio
+else
+APP_THIRD_PARTY_LIBS += -lportaudio-$(TARGET_NAME)
+APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libportaudio-$(LIB_SUFFIX)
+endif
+endif
+
+# Additional flags
+@ac_build_mak_vars@
+
+#
+# Video
+# Note: there are duplicated macros in pjmedia/os-auto.mak.in (and that's not
+#       good!
+
+# SDL flags
+SDL_CFLAGS = @ac_sdl_cflags@
+SDL_LDFLAGS = @ac_sdl_ldflags@
+
+# FFMPEG dlags
+FFMPEG_CFLAGS = @ac_ffmpeg_cflags@ 
+FFMPEG_LDFLAGS =  @ac_ffmpeg_ldflags@
+
+# Video4Linux2
+V4L2_CFLAGS = @ac_v4l2_cflags@
+V4L2_LDFLAGS = @ac_v4l2_ldflags@
+
+# QT
+AC_PJMEDIA_VIDEO_HAS_QT = @ac_pjmedia_video_has_qt@
+QT_CFLAGS = @ac_qt_cflags@
+
+# iOS
+IOS_CFLAGS = @ac_ios_cflags@
+
+# PJMEDIA features exclusion
+PJ_VIDEO_CFLAGS += $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(QT_CFLAGS) \
+		   $(IOS_CFLAGS)
+PJ_VIDEO_LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS)
+
+
+# CFLAGS, LDFLAGS, and LIBS to be used by applications
+export APP_CC := @CC@
+export APP_CXX := @CXX@
+export APP_CFLAGS := -DPJ_AUTOCONF=1\
+	@CFLAGS@\
+	$(PJ_VIDEO_CFLAGS) \
+	-I$(PJDIR)/pjlib/include\
+	-I$(PJDIR)/pjlib-util/include\
+	-I$(PJDIR)/pjnath/include\
+	-I$(PJDIR)/pjmedia/include\
+	-I$(PJDIR)/pjsip/include
+export APP_CXXFLAGS := $(APP_CFLAGS)
+export APP_LDFLAGS := -L$(PJDIR)/pjlib/lib\
+	-L$(PJDIR)/pjlib-util/lib\
+	-L$(PJDIR)/pjnath/lib\
+	-L$(PJDIR)/pjmedia/lib\
+	-L$(PJDIR)/pjsip/lib\
+	-L$(PJDIR)/third_party/lib\
+	$(PJ_VIDEO_LDFLAGS) \
+	@LDFLAGS@
+export APP_LDLIBS := -lpjsua-$(TARGET_NAME)\
+	-lpjsip-ua-$(TARGET_NAME)\
+	-lpjsip-simple-$(TARGET_NAME)\
+	-lpjsip-$(TARGET_NAME)\
+	-lpjmedia-codec-$(TARGET_NAME)\
+	-lpjmedia-videodev-$(TARGET_NAME)\
+	-lpjmedia-$(TARGET_NAME)\
+	-lpjmedia-audiodev-$(TARGET_NAME)\
+	-lpjnath-$(TARGET_NAME)\
+	-lpjlib-util-$(TARGET_NAME)\
+	$(APP_THIRD_PARTY_LIBS)\
+	$(APP_THIRD_PARTY_EXT)\
+	-lpj-$(TARGET_NAME)\
+	@LIBS@
+export APP_LIB_FILES = $(PJ_DIR)/pjsip/lib/libpjsua-$(LIB_SUFFIX) \
+	$(PJ_DIR)/pjsip/lib/libpjsip-ua-$(LIB_SUFFIX) \
+	$(PJ_DIR)/pjsip/lib/libpjsip-simple-$(LIB_SUFFIX) \
+	$(PJ_DIR)/pjsip/lib/libpjsip-$(LIB_SUFFIX) \
+	$(PJ_DIR)/pjmedia/lib/libpjmedia-codec-$(LIB_SUFFIX) \
+	$(PJ_DIR)/pjmedia/lib/libpjmedia-videodev-$(LIB_SUFFIX) \
+	$(PJ_DIR)/pjmedia/lib/libpjmedia-$(LIB_SUFFIX) \
+	$(PJ_DIR)/pjmedia/lib/libpjmedia-audiodev-$(LIB_SUFFIX) \
+	$(PJ_DIR)/pjnath/lib/libpjnath-$(LIB_SUFFIX) \
+	$(PJ_DIR)/pjlib-util/lib/libpjlib-util-$(LIB_SUFFIX) \
+	$(APP_THIRD_PARTY_LIB_FILES) \
+	$(PJ_DIR)/pjlib/lib/libpj-$(LIB_SUFFIX)
+
+# Here are the variabels to use if application is using the library
+# from within the source distribution
+export PJ_CC := $(APP_CC)
+export PJ_CXX := $(APP_CXX)
+export PJ_CFLAGS := $(APP_CFLAGS)
+export PJ_CXXFLAGS := $(APP_CXXFLAGS)
+export PJ_LDFLAGS := $(APP_LDFLAGS)
+export PJ_LDLIBS := $(APP_LDLIBS)
+export PJ_LIB_FILES := $(APP_LIB_FILES)
+
+# And here are the variables to use if application is using the
+# library from the install location (i.e. --prefix)
+export PJ_INSTALL_DIR := @prefix@
+export PJ_INSTALL_INC_DIR := $(PJ_INSTALL_DIR)/include
+export PJ_INSTALL_LIB_DIR := $(PJ_INSTALL_DIR)/lib
+export PJ_INSTALL_CFLAGS := -I$(PJ_INSTALL_INC_DIR) -DPJ_AUTOCONF=1	@CFLAGS@
+export PJ_INSTALL_CXXFLAGS := $(PJ_INSTALL_CFLAGS)
+export PJ_INSTALL_LDFLAGS := -L$(PJ_INSTALL_LIB_DIR) $(APP_LDLIBS)
diff --git a/jni/pjproject-android/.svn/pristine/2d/2dd4577afa6aeba079fd3e722821cdc9c450fa10.svn-base b/jni/pjproject-android/.svn/pristine/2d/2dd4577afa6aeba079fd3e722821cdc9c450fa10.svn-base
new file mode 100644
index 0000000..f315599
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2dd4577afa6aeba079fd3e722821cdc9c450fa10.svn-base
@@ -0,0 +1,395 @@
+/**
+ 
+@mainpage Introduction to libSRTP
+ 
+This document describes libSRTP, the Open Source Secure RTP library
+from Cisco Systems, Inc.  RTP is the Real-time Transport Protocol, an
+IETF standard for the transport of real-time data such as telephony,
+audio, and video, defined by RFC1889.  Secure RTP (SRTP) is an RTP
+profile for providing confidentiality to RTP data and authentication
+to the RTP header and payload.  SRTP is an IETF Proposed Standard, and
+is defined in RFC 3711, and was developed in the IETF Audio/Video
+Transport (AVT) Working Group.  This library supports all of the
+mandatory features of SRTP, but not all of the optional features.  See
+the @ref Features section for more detailed information.
+ 
+This document is organized as follows.  The first chapter provides 
+background material on SRTP and overview of libSRTP.  The following
+chapters provide a detailed reference to the libSRTP API and related
+functions.  The reference material is created automatically (using the
+doxygen utility) from comments embedded in some of the C header
+files. The documentation is organized into modules in order to improve
+its clarity.  These modules do not directly correspond to files. An
+underlying cryptographic kernel provides much of the basic
+functionality of libSRTP, but is mostly undocumented because it does
+its work behind the scenes.
+
+@section LICENSE License and Disclaimer
+
+libSRTP is distributed under the following license, which is included
+in the source code distribution.  It is reproduced in the manual in
+case you got the library from another source.
+	
+@latexonly
+\begin{quote}
+Copyright (c) 2001-2005 Cisco Systems, Inc.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+\begin{itemize}
+\item  Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+\item 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.
+\item Neither the name of the Cisco Systems, Inc. nor the names of its
+  contributors may be used to endorse or promote products derived
+  from this software without specific prior written permission.
+\end{itemize}
+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
+COPYRIGHT HOLDERS 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.
+\end{quote}
+@endlatexonly
+
+@section Features Supported Features
+
+This library supports all of the mandatory-to-implement features of
+SRTP (as defined by the most recent Internet Draft).  Some of these
+features can be selected (or de-selected) at run time by setting an
+appropriate policy; this is done using the structure srtp_policy_t.
+Some other behaviors of the protocol can be adapted by defining an
+approriate event handler for the exceptional events; see the @ref
+SRTPevents section.  
+
+Some options that are not included in the specification are supported.
+Most notably, the TMMH authentication function is included, though it
+was removed from the SRTP Internet Draft during the summer of 2002.
+
+
+@latexonly
+Some options that are described in the SRTP specification are not
+supported.  This includes 
+\begin{itemize}
+\item the Master Key Index (MKI),
+\item key derivation rates other than zero,
+\item the cipher F8,
+\item anti-replay lists with sizes other than 128,
+\item the use of the packet index to select between master keys.
+\end{itemize}
+@endlatexonly
+ 
+The user should be aware that it is possible to misuse this libary,
+and that the result may be that the security level it provides is
+inadequate.  If you are implementing a feature using this library, you
+will want to read the Security Considerations section of the Internet
+Draft.  In addition, it is important that you read and understand the
+terms outlined in the @ref LICENSE section.
+
+
+@section Installing Installing and Building libSRTP
+
+@latexonly
+
+To install libSRTP, download the latest release of the distribution
+from \texttt{srtp.sourceforge.net}.  The format of the names of the
+distributions are \texttt{srtp-A.B.C.tgz}, where \texttt{A} is the
+version number, \texttt{B} is the major release number, \texttt{C} is
+the minor release number, and \texttt{tgz} is the file
+extension\footnote{The extension \texttt{.tgz} is identical to
+\texttt{tar.gz}, and indicates a compressed tar file.}  You probably
+want to get the most recent release.  Unpack the distribution and
+extract the source files; the directory into which the soruce files
+will go is named \texttt{srtp}.
+
+libSRTP uses the GNU \texttt{autoconf} and \texttt{make}
+utilities\footnote{BSD make will not work; if both versions of make
+are on your platform, you can invoke GNU make as \texttt{gmake}.}.  In
+the \texttt{srtp} directory, run the configure script and then make:
+\begin{verbatim}
+  ./configure [ options ]       
+  make                          
+\end{verbatim}
+The configure script accepts the following options:
+\begin{quote}
+\begin{description}
+\item[--help]              provides a usage summary.
+\item[--disable-debug]     compiles libSRTP without the runtime 
+			   dynamic debugging system.
+\item[--enable-generic-aesicm] compile in changes for ismacryp
+\item[--enable-syslog]     use syslog for error reporting.
+\item[--disable-stdout]    diables stdout for error reporting.
+\item[--enable-console]    use \texttt{/dev/console} for error reporting
+\item[--gdoi]              use GDOI key management (disabled at present).
+\end{description}
+\end{quote}
+
+By default, dynamic debbuging is enabled and stdout is used for
+debugging.  You can use the configure options to have the debugging
+output sent to syslog or the system console.  Alternatively, you can
+define ERR\_REPORTING\_FILE in \texttt{include/conf.h} to be any other
+file that can be opened by libSRTP, and debug messages will be sent to
+it.
+
+This package has been tested on the following platforms: Mac OS X
+(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris
+(sparc-sun-solaris2.6), RedHat Linux 7.1 and 9 (i686-pc-linux), and
+OpenBSD (sparc-unknown-openbsd2.7).
+
+
+@endlatexonly
+
+@section Applications Applications
+
+@latexonly
+
+Several test drivers and a simple and portable srtp application are
+included in the \texttt{test/} subdirectory.
+
+\begin{center}
+\begin{tabular}{ll}
+\hline
+Test driver    	& Function tested	\\
+\hline
+kernel\_driver   & crypto kernel (ciphers, auth funcs, rng) \\
+srtp\_driver	& srtp in-memory tests (does not use the network) \\
+rdbx\_driver	& rdbx (extended replay database) \\
+roc\_driver	& extended sequence number functions \\ 
+replay\_driver	& replay database  \\
+cipher\_driver	& ciphers  \\
+auth\_driver	& hash functions \\
+\hline
+\end{tabular}
+\end{center}
+
+The app rtpw is a simple rtp application which reads words from
+/usr/dict/words and then sends them out one at a time using [s]rtp.
+Manual srtp keying uses the -k option; automated key management
+using gdoi will be added later.
+
+The usage for rtpw is
+
+\texttt{rtpw [[-d $<$debug$>$]* [-k $<$key$>$ [-a][-e]] [-s | -r] dest\_ip
+dest\_port][-l]}
+
+Either the -s (sender) or -r (receiver) option must be chosen.  The
+values dest\_ip, dest\_port are the IP address and UDP port to which
+the dictionary will be sent, respectively.  The options are:
+\begin{center}
+\begin{tabular}{ll}
+  -s		& (S)RTP sender - causes app to send words \\
+  -r		& (S)RTP receive - causes app to receve words \\
+  -k $<$key$>$      & use SRTP master key $<$key$>$, where the 
+		key is a hexadecimal value (without the
+                leading "0x") \\
+  -e            & encrypt/decrypt (for data confidentiality)
+                (requires use of -k option as well)\\
+  -a            & message authentication 
+                (requires use of -k option as well) \\
+  -l            & list the avaliable debug modules \\
+  -d $<$debug$>$    & turn on debugging for module $<$debug$>$ \\
+\end{tabular}
+\end{center}
+
+In order to get a random 30-byte value for use as a key/salt pair, you
+can use the \texttt{rand\_gen} utility in the \texttt{test/}
+subdirectory.
+
+An example of an SRTP session using two rtpw programs follows:
+
+\begin{verbatim}
+[sh1] set k=`test/rand_gen -n 30`
+[sh1] echo $k
+c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
+[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999 
+Security services: confidentiality message authentication
+set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
+setting SSRC to 2078917053
+sending word: A
+sending word: a
+sending word: aa
+sending word: aal
+sending word: aalii
+sending word: aam
+sending word: Aani
+sending word: aardvark
+...
+
+[sh2] set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
+[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999 
+security services: confidentiality message authentication
+set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
+19 octets received from SSRC 2078917053 word: A
+19 octets received from SSRC 2078917053 word: a
+20 octets received from SSRC 2078917053 word: aa
+21 octets received from SSRC 2078917053 word: aal
+...
+\end{verbatim}
+
+
+@endlatexonly
+
+
+@section Review Secure RTP Background
+
+In this section we review SRTP and introduce some terms that are used
+in libSRTP.  An RTP session is defined by a pair of destination
+transport addresses, that is, a network address plus a pair of UDP
+ports for RTP and RTCP.  RTCP, the RTP control protocol, is used to
+coordinate between the participants in an RTP session, e.g. to provide
+feedback from receivers to senders.  An @e SRTP @e session is
+similarly defined; it is just an RTP session for which the SRTP
+profile is being used.  An SRTP session consists of the traffic sent
+to the SRTP or SRTCP destination transport addresses.  Each
+participant in a session is identified by a synchronization source
+(SSRC) identifier.  Some participants may not send any SRTP traffic;
+they are called receivers, even though they send out SRTCP traffic,
+such as receiver reports.
+
+RTP allows multiple sources to send RTP and RTCP traffic during the
+same session.  The synchronization source identifier (SSRC) is used to
+distinguish these sources.  In libSRTP, we call the SRTP and SRTCP
+traffic from a particular source a @e stream.  Each stream has its own
+SSRC, sequence number, rollover counter, and other data.  A particular
+choice of options, cryptographic mechanisms, and keys is called a @e
+policy.  Each stream within a session can have a distinct policy
+applied to it.  A session policy is a collection of stream policies.
+
+A single policy can be used for all of the streams in a given session,
+though the case in which a single @e key is shared across multiple
+streams requires care.  When key sharing is used, the SSRC values that
+identify the streams @b must be distinct.  This requirement can be
+enforced by using the convention that each SRTP and SRTCP key is used
+for encryption by only a single sender.  In other words, the key is
+shared only across streams that originate from a particular device (of
+course, other SRTP participants will need to use the key for
+decryption).  libSRTP supports this enforcement by detecting the case
+in which a key is used for both inbound and outbound data.
+
+
+@section Overview libSRTP Overview
+
+libSRTP provides functions for protecting RTP and RTCP.  RTP packets
+can be encrypted and authenticated (using the srtp_protect()
+function), turning them into SRTP packets.  Similarly, SRTP packets
+can be decrypted and have their authentication verified (using the
+srtp_unprotect() function), turning them into RTP packets.  Similar
+functions apply security to RTCP packets.
+
+The typedef srtp_stream_t points to a structure holding all of the
+state associated with an SRTP stream, including the keys and
+parameters for cipher and message authentication functions and the
+anti-replay data.  A particular srtp_stream_t holds the information
+needed to protect a particular RTP and RTCP stream.  This datatype
+is intentionally opaque in order to better seperate the libSRTP
+API from its implementation.
+
+Within an SRTP session, there can be multiple streams, each
+originating from a particular sender.  Each source uses a distinct
+stream context to protect the RTP and RTCP stream that it is
+originating.  The typedef srtp_t points to a structure holding all of
+the state associated with an SRTP session.  There can be multiple
+stream contexts associated with a single srtp_t.  A stream context
+cannot exist indepent from an srtp_t, though of course an srtp_t can
+be created that contains only a single stream context.  A device
+participating in an SRTP session must have a stream context for each
+source in that session, so that it can process the data that it
+receives from each sender.
+
+
+In libSRTP, a session is created using the function srtp_create().
+The policy to be implemented in the session is passed into this
+function as an srtp_policy_t structure.  A single one of these
+structures describes the policy of a single stream.  These structures
+can also be linked together to form an entire session policy.  A linked
+list of srtp_policy_t structures is equivalent to a session policy.  
+In such a policy, we refer to a single srtp_policy_t as an @e element.
+
+An srtp_policy_t strucutre contains two crypto_policy_t structures
+that describe the cryptograhic policies for RTP and RTCP, as well as
+the SRTP master key and the SSRC value.  The SSRC describes what to
+protect (e.g. which stream), and the crypto_policy_t structures
+describe how to protect it.  The key is contained in a policy element
+because it simplifies the interface to the library.  In many cases, it
+is desirable to use the same cryptographic policies across all of the
+streams in a session, but to use a distinct key for each stream.  A
+crypto_policy_t structure can be initialized by using either the
+crypto_policy_set_rtp_default() or crypto_policy_set_rtcp_default()
+functions, which set a crypto policy structure to the default policies
+for RTP and RTCP protection, respectively.
+				   
+@section Example Example Code
+
+This section provides a simple example of how to use libSRTP.  The
+example code lacks error checking, but is functional.  Here we assume
+that the value ssrc is already set to describe the SSRC of the stream
+that we are sending, and that the functions get_rtp_packet() and
+send_srtp_packet() are available to us.  The former puts an RTP packet
+into the buffer and returns the number of octets written to that
+buffer.  The latter sends the RTP packet in the buffer, given the
+length as its second argument.
+
+@verbatim
+   srtp_t session;   
+   srtp_policy_t policy;
+   uint8_t key[30];
+
+   // initialize libSRTP 
+   srtp_init();                                  
+
+   // set policy to describe a policy for an SRTP stream 
+   crypto_policy_set_rtp_default(&policy.rtp);   
+   crypto_policy_set_rtcp_default(&policy.rtcp); 
+   policy.ssrc = ssrc;                            
+   policy.key  = key;
+   policy.next = NULL;
+
+   // set key to random value 
+   crypto_get_random(key, 30);          
+
+   // allocate and initialize the SRTP session 
+   srtp_create(&session, policy);  
+   
+   // main loop: get rtp packets, send srtp packets
+   while (1) {
+      char rtp_buffer[2048];
+      unsigned len;
+
+      len = get_rtp_packet(rtp_buffer);
+      srtp_protect(session, rtp_buffer, &len);
+      send_srtp_packet(rtp_buffer, len);
+   }
+@endverbatim
+
+@section ISMAcryp ISMA Encryption Support
+
+The Internet Streaming Media Alliance (ISMA) specifies a way 
+to pre-encrypt a media file prior to streaming.  This method
+is an alternative to SRTP encryption, which is potentially
+useful when a particular media file will be streamed
+multiple times.  The specification is available online 
+at  http://www.isma.tv/specreq.nsf/SpecRequest.
+
+libSRTP provides the encryption and decryption functions needed for ISMAcryp
+in the library @t libaesicm.a, which is included in the default
+Makefile target.  This library is used by the MPEG4IP project; see 
+http://mpeg4ip.sourceforge.net/.
+
+Note that ISMAcryp does not provide authentication for 
+RTP nor RTCP, nor confidentiality for RTCP.  
+ISMAcryp RECOMMENDS the use of SRTP message authentication for ISMAcryp
+streams while using ISMAcryp encryption to protect the media itself.
+
+
+ */
diff --git a/jni/pjproject-android/.svn/pristine/2d/2dda37db44b406e4b97b17a3c3cd3c07ee5fdc0d.svn-base b/jni/pjproject-android/.svn/pristine/2d/2dda37db44b406e4b97b17a3c3cd3c07ee5fdc0d.svn-base
new file mode 100644
index 0000000..5eec3b2
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2dda37db44b406e4b97b17a3c3cd3c07ee5fdc0d.svn-base
@@ -0,0 +1,34 @@
+:
+#
+# 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.
+#
+if [ ! -f 1.inp ] ; then
+	echo Sorry, but we cannot provide the test data with this release.
+	exit
+fi
+
+echo -n 'Linear to code: '
+for i in 1 2 3 4
+do 
+	echo -n $i..
+ 	./lin2cod  < $i.inp | cmp - $i.cod
+done
+echo ""
+
+echo -n 'Code to linear: '
+for i in 1 2 3 4
+do 
+	echo -n $i..
+	./cod2lin < $i.cod | cmp - $i.out
+done
+echo ""
+
+echo -n 'Toast: '
+for i in 1 2 3 4
+do
+	echo -n $i..
+	../bin/toast -l < $i.inp | ../bin/toast -dl | cmp - $i.out
+done
+echo ""
diff --git a/jni/pjproject-android/.svn/pristine/2d/2deb16b511172313f8cdf6428af25110637ddaa6.svn-base b/jni/pjproject-android/.svn/pristine/2d/2deb16b511172313f8cdf6428af25110637ddaa6.svn-base
new file mode 100644
index 0000000..3414f17
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2deb16b511172313f8cdf6428af25110637ddaa6.svn-base
@@ -0,0 +1,12 @@
+# $Id$
+#
+from inc_cfg import *
+
+# TCP call
+test_param = TestParam(
+		"TCP transport",
+		[
+			InstanceParam("callee", "--null-audio --no-udp --max-calls=1", uri_param=";transport=tcp"),
+			InstanceParam("caller", "--null-audio --no-udp --max-calls=1")
+		]
+		)
diff --git a/jni/pjproject-android/.svn/pristine/2d/2df0bd23e447e1c5d5e10b0ed498b4165570bc61.svn-base b/jni/pjproject-android/.svn/pristine/2d/2df0bd23e447e1c5d5e10b0ed498b4165570bc61.svn-base
new file mode 100644
index 0000000..cc139f7
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/2d/2df0bd23e447e1c5d5e10b0ed498b4165570bc61.svn-base
@@ -0,0 +1,237 @@
+/* $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 
+ */
+
+ /**
+ * \page page_pjmedia_samples_mix_c Samples: Mixing WAV files
+ *
+ * This file is pjsip-apps/src/samples/mix.c
+ *
+ * \includelineno mix.c
+ */
+
+#include <pjlib.h>
+#include <pjlib-util.h>
+#include <pjmedia.h>
+
+#define THIS_FILE   "mix.c"
+
+static const char *desc = 
+ " mix\n"
+ "\n"
+ " PURPOSE:\n"
+ "  Mix input WAV files and save it to output WAV. Input WAV can have\n"
+ "  different clock rate.\n"
+ "\n"
+ "\n"
+ " USAGE:\n"
+ "  mix [options] output.wav input1.wav [input2.wav] ...\n"
+ "\n"
+ " arguments:\n"
+ "    output.wav    Set the output WAV filename.\n"
+ "    input1.wav    Set the input WAV filename.\n"
+ "    input2.wav    Set the input WAV filename.\n"
+ "\n"
+ " options:\n"
+ "    -c N          Set clock rate to N Hz (default 16000)\n"
+ "    -f            Force write (overwrite output without warning\n"
+;
+
+#define MAX_WAV	    16
+#define PTIME	    20
+#define APPEND	    1000
+
+struct wav_input
+{
+    const char	    *fname;
+    pjmedia_port    *port;
+    unsigned	     slot;
+};
+
+static int err_ret(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(3,(THIS_FILE, "%s error: %s", title, errmsg));
+    return 1;
+}
+
+static void usage(void)
+{
+    puts(desc);
+}
+
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pj_pool_t *pool;
+    pjmedia_endpt *med_ept;
+    unsigned clock_rate = 16000;
+    int c, force=0;
+    const char *out_fname;
+    pjmedia_conf *conf;
+    pjmedia_port *wavout;
+    struct wav_input wav_input[MAX_WAV];
+    pj_size_t longest = 0, processed;
+    unsigned i, input_cnt = 0;
+    pj_status_t status;
+
+#define CHECK(op)   do { \
+			status = op; \
+			if (status != PJ_SUCCESS) \
+			    return err_ret(#op, status); \
+		    } while (0)
+
+
+    /* Parse arguments */
+    while ((c=pj_getopt(argc, argv, "c:f")) != -1) {
+	switch (c) {
+	case 'c':
+	    clock_rate = atoi(pj_optarg);
+	    if (clock_rate < 1000) {
+		puts("Error: invalid clock rate");
+		usage();
+		return -1;
+	    }
+	    break;
+	case 'f':
+	    force = 1;
+	    break;
+	}
+    }
+
+    /* Get output WAV name */
+    if (pj_optind == argc) {
+	puts("Error: no WAV output is specified");
+	usage();
+	return 1;
+    }
+
+    out_fname = argv[pj_optind++];
+    if (force==0 && pj_file_exists(out_fname)) {
+	char in[8];
+
+	printf("File %s exists, overwrite? [Y/N] ", out_fname);
+	fflush(stdout);
+	if (fgets(in, sizeof(in), stdin) == NULL)
+	    return 1;
+	if (pj_tolower(in[0]) != 'y')
+	    return 1;
+    }
+
+    /* Scan input file names */
+    for (input_cnt=0 ; pj_optind<argc && input_cnt<MAX_WAV; 
+	 ++pj_optind, ++input_cnt) 
+    {
+	if (!pj_file_exists(argv[pj_optind])) {
+	    printf("Error: input file %s doesn't exist\n",
+		   argv[pj_optind]);
+	    return 1;
+	}
+	wav_input[input_cnt].fname = argv[pj_optind];
+	wav_input[input_cnt].port = NULL;
+	wav_input[input_cnt].slot = 0;
+    }
+
+    if (input_cnt == 0) {
+	puts("Error: no input WAV is specified");
+	return 0;
+    }
+
+    /* Initialialize */
+    CHECK( pj_init() );
+    CHECK( pjlib_util_init() );
+    pj_caching_pool_init(&cp, NULL, 0);
+    CHECK( pjmedia_endpt_create(&cp.factory, NULL, 1, &med_ept) );
+
+    pool = pj_pool_create(&cp.factory, "mix", 1000, 1000, NULL);
+
+    /* Create the bridge */
+    CHECK( pjmedia_conf_create(pool, MAX_WAV+4, clock_rate, 1, 
+			       clock_rate * PTIME / 1000, 16, 
+			       PJMEDIA_CONF_NO_DEVICE, &conf) );
+
+    /* Create the WAV output */
+    CHECK( pjmedia_wav_writer_port_create(pool, out_fname, clock_rate, 1,
+					  clock_rate * PTIME / 1000,
+					  16, 0, 0, &wavout) );
+
+    /* Create and register each WAV input to the bridge */
+    for (i=0; i<input_cnt; ++i) {
+	pj_ssize_t len;
+
+	CHECK( pjmedia_wav_player_port_create(pool, wav_input[i].fname, 20,
+					      PJMEDIA_FILE_NO_LOOP, 0, 
+					      &wav_input[i].port) );
+	len = pjmedia_wav_player_get_len(wav_input[i].port);
+	len = (pj_ssize_t)(len * 1.0 * clock_rate / 
+			   PJMEDIA_PIA_SRATE(&wav_input[i].port->info));
+	if (len > (pj_ssize_t)longest)
+	    longest = len;
+
+	CHECK( pjmedia_conf_add_port(conf, pool, wav_input[i].port,
+				     NULL, &wav_input[i].slot));
+
+	CHECK( pjmedia_conf_connect_port(conf, wav_input[i].slot, 0, 0) );
+    }
+
+    /* Loop reading frame from the bridge and write it to WAV */
+    processed = 0;
+    while (processed < longest + clock_rate * APPEND * 2 / 1000) {
+	pj_int16_t framebuf[PTIME * 48000 / 1000];
+	pjmedia_port *cp = pjmedia_conf_get_master_port(conf);
+	pjmedia_frame frame;
+
+	frame.buf = framebuf;
+	frame.size = PJMEDIA_PIA_SPF(&cp->info) * 2;
+	pj_assert(frame.size <= sizeof(framebuf));
+	
+	CHECK( pjmedia_port_get_frame(cp, &frame) );
+
+	if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {
+	    pj_bzero(frame.buf, frame.size);
+	    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+	}
+
+	CHECK( pjmedia_port_put_frame(wavout, &frame));
+
+	processed += frame.size;
+    }
+
+    PJ_LOG(3,(THIS_FILE, "Done. Output duration: %d.%03d",
+	      (processed >> 2)/clock_rate,
+	      ((processed >> 2)*1000/clock_rate) % 1000));
+
+    /* Shutdown everything */
+    CHECK( pjmedia_port_destroy(wavout) );
+    for (i=0; i<input_cnt; ++i) {
+	CHECK( pjmedia_conf_remove_port(conf, wav_input[i].slot) );
+	CHECK( pjmedia_port_destroy(wav_input[i].port) );
+    }
+
+    CHECK(pjmedia_conf_destroy(conf));
+    CHECK(pjmedia_endpt_destroy(med_ept));
+
+    pj_pool_release(pool);
+    pj_caching_pool_destroy(&cp);
+    pj_shutdown();
+
+    return 0;
+}
+