diff --git a/.gitmodules b/.gitmodules
index b6715c22c..9b6f29f6c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -64,3 +64,6 @@
[submodule "submodules/externals/libupnp"]
path = submodules/externals/libupnp
url = git://git.code.sf.net/p/pupnp/code
+[submodule "submodules/externals/cunit"]
+ path = submodules/externals/cunit
+ url = gitosis@git.linphone.org:cunit.git
diff --git a/Makefile b/Makefile
index e28ed6af1..a50dedbca 100644
--- a/Makefile
+++ b/Makefile
@@ -107,6 +107,14 @@ BELLESIP_SRC_DIR=$(TOPDIR)/submodules/belle-sip
BELLESIP_BUILD_DIR=$(BELLESIP_SRC_DIR)
prepare-belle-sip: $(BELLESIP_SRC_DIR)/src/belle_sip_message.tokens $(BELLESIP_SRC_DIR)/src/belle_sdp.tokens
+prepare-cunit: $(TOPDIR)/submodules/externals/cunit/CUnit/Headers/*.h
+ [ -d $(TOPDIR)/submodules/externals/build/cunit/CUnit ] || mkdir $(TOPDIR)/submodules/externals/build/cunit/CUnit
+ cp $^ $(TOPDIR)/submodules/externals/build/cunit/CUnit
+
+prepare-liblinphone_tester: $(TOPDIR)/submodules/linphone/tester/*_lrc $(TOPDIR)/submodules/linphone/tester/*_rc
+# [ -d $(TOPDIR)/liblinphone_tester/res/raw ] || mkdir $(TOPDIR)/liblinphone_tester/res/raw
+# cp $^ $(TOPDIR)/liblinphone_tester/res/raw
+
prepare-sources: prepare-ffmpeg prepare-ilbc prepare-vpx prepare-silk prepare-srtp prepare-mediastreamer2 prepare-antlr3 prepare-belle-sip
generate-libs: prepare-sources
@@ -115,6 +123,9 @@ generate-libs: prepare-sources
update-project:
$(SDK_PATH)/android update project --path . --target $(ANDROID_MOST_RECENT_TARGET)
+liblinphone_tester: prepare-sources prepare-cunit prepare-liblinphone_tester
+ $(NDK_PATH)/ndk-build -C liblinphone_tester NDK_DEBUG=1 LINPHONE_VERSION=$(LINPHONE_VERSION) BUILD_UPNP=$(BUILD_UPNP) BUILD_REMOTE_PROVISIONING=$(BUILD_REMOTE_PROVISIONING) BUILD_X264=$(BUILD_X264) BUILD_AMRNB=$(BUILD_AMRNB) BUILD_AMRWB=$(BUILD_AMRWB) BUILD_GPLV3_ZRTP=$(BUILD_GPLV3_ZRTP) BUILD_SILK=$(BUILD_SILK) BUILD_G729=$(BUILD_G729) BUILD_TUNNEL=$(BUILD_TUNNEL) BUILD_WEBRTC_AECM=$(BUILD_WEBRTC_AECM) BUILD_FOR_X86=$(BUILD_FOR_X86) USE_JAVAH=$(USE_JAVAH) -j$(NUMCPUS)
+
generate-apk:
ant partial-clean
echo "version.name=$(LINPHONE_ANDROID_DEBUG_VERSION)" > default.properties
diff --git a/liblinphone_tester/.classpath b/liblinphone_tester/.classpath
new file mode 100644
index 000000000..08e877a4e
--- /dev/null
+++ b/liblinphone_tester/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/liblinphone_tester/.gitignore b/liblinphone_tester/.gitignore
new file mode 100644
index 000000000..00dfbd2c3
--- /dev/null
+++ b/liblinphone_tester/.gitignore
@@ -0,0 +1,18 @@
+# built application files
+*.apk
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+
+# generated files
+bin/
+gen/
+libs/
+obj/
+
+# Local configuration file (sdk path, etc)
+local.properties
diff --git a/liblinphone_tester/.project b/liblinphone_tester/.project
new file mode 100644
index 000000000..15cf6a0c3
--- /dev/null
+++ b/liblinphone_tester/.project
@@ -0,0 +1,40 @@
+
+
+ liblinphoneTester
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
+
+ mediastreamer2
+ 2
+ /Users/ydiorcet/Desktop/linphone-android/submodules/linphone/mediastreamer2/java/src
+
+
+
diff --git a/liblinphone_tester/AndroidManifest.xml b/liblinphone_tester/AndroidManifest.xml
new file mode 100644
index 000000000..95dfc350d
--- /dev/null
+++ b/liblinphone_tester/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/liblinphone_tester/jni/Android.mk b/liblinphone_tester/jni/Android.mk
new file mode 100644
index 000000000..bacf8a993
--- /dev/null
+++ b/liblinphone_tester/jni/Android.mk
@@ -0,0 +1,3 @@
+include ../jni/Android.mk
+include $(linphone-root-dir)/submodules/externals/build/cunit/Android.mk
+include $(linphone-root-dir)/submodules/linphone/build/android/liblinphone_tester.mk
diff --git a/liblinphone_tester/jni/Application.mk b/liblinphone_tester/jni/Application.mk
new file mode 100644
index 000000000..1e824c4cd
--- /dev/null
+++ b/liblinphone_tester/jni/Application.mk
@@ -0,0 +1,7 @@
+LOCAL_PATH:= $(call my-dir)
+include ../jni/Application.mk
+APP_PROJECT_PATH := $(LOCAL_PATH)/../
+APP_BUILD_SCRIPT := $(LOCAL_PATH)/Android.mk
+APP_OPTIM := debug
+
+APP_MODULES += cunit liblinphone_tester liblinphone_testernoneon
diff --git a/liblinphone_tester/res/drawable-hdpi/ic_launcher.png b/liblinphone_tester/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 000000000..96a442e5b
Binary files /dev/null and b/liblinphone_tester/res/drawable-hdpi/ic_launcher.png differ
diff --git a/liblinphone_tester/res/drawable-mdpi/ic_launcher.png b/liblinphone_tester/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 000000000..359047dfa
Binary files /dev/null and b/liblinphone_tester/res/drawable-mdpi/ic_launcher.png differ
diff --git a/liblinphone_tester/res/drawable-xhdpi/ic_launcher.png b/liblinphone_tester/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..71c6d760f
Binary files /dev/null and b/liblinphone_tester/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/liblinphone_tester/res/layout/activity_main.xml b/liblinphone_tester/res/layout/activity_main.xml
new file mode 100644
index 000000000..69f4752d0
--- /dev/null
+++ b/liblinphone_tester/res/layout/activity_main.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/liblinphone_tester/res/menu/activity_main.xml b/liblinphone_tester/res/menu/activity_main.xml
new file mode 100644
index 000000000..77f358b68
--- /dev/null
+++ b/liblinphone_tester/res/menu/activity_main.xml
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/liblinphone_tester/res/raw/laure_rc b/liblinphone_tester/res/raw/laure_rc
new file mode 100644
index 000000000..443c4e918
--- /dev/null
+++ b/liblinphone_tester/res/raw/laure_rc
@@ -0,0 +1,42 @@
+[net]
+mtu=1300
+
+[sip]
+sip_port=5092
+sip_tcp_port=5092
+sip_tls_port=5093
+default_proxy=0
+ping_with_options=0
+register_only_when_network_is_up=0
+
+[auth_info_0]
+username=laure
+userid=laure
+passwd=secret
+realm="sip.example.org"
+
+
+[proxy_0]
+reg_proxy=sip2.linphone.org
+reg_route=sip2.linphone.org
+reg_identity=sip:laure@sip.example.org
+reg_expires=3600
+reg_sendregister=1
+publish=0
+dial_escape_plus=0
+
+
+[rtp]
+audio_rtp_port=9010
+video_rtp_port=9012
+
+[video]
+display=0
+capture=0
+show_local=0
+size=vga
+enabled=0
+self_view=0
+automatically_initiate=0
+automatically_accept=0
+device=StaticImage: Static picture
\ No newline at end of file
diff --git a/liblinphone_tester/res/raw/marie_rc b/liblinphone_tester/res/raw/marie_rc
new file mode 100644
index 000000000..760db76ba
--- /dev/null
+++ b/liblinphone_tester/res/raw/marie_rc
@@ -0,0 +1,47 @@
+[net]
+mtu=1300
+
+[sip]
+sip_port=5082
+sip_tcp_port=5082
+sip_tls_port=5083
+default_proxy=0
+ping_with_options=0
+register_only_when_network_is_up=0
+
+[auth_info_0]
+username=marie
+userid=marie
+passwd=secret
+realm="sip.example.org"
+
+
+[proxy_0]
+reg_proxy=sip2.linphone.org;transport=tcp
+reg_route=sip2.linphone.org;transport=tcp;lr
+reg_identity=sip:marie@sip.example.org
+reg_expires=3600
+reg_sendregister=1
+publish=0
+dial_escape_plus=0
+
+[friend_0]
+url="Paupoche"
+pol=accept
+subscribe=0
+
+
+[rtp]
+audio_rtp_port=8070
+video_rtp_port=8072
+
+[video]
+display=0
+capture=0
+show_local=0
+size=vga
+enabled=0
+self_view=0
+automatically_initiate=0
+automatically_accept=0
+device=StaticImage: Static picture
\ No newline at end of file
diff --git a/liblinphone_tester/res/raw/multi_account_lrc b/liblinphone_tester/res/raw/multi_account_lrc
new file mode 100644
index 000000000..ea24951a3
--- /dev/null
+++ b/liblinphone_tester/res/raw/multi_account_lrc
@@ -0,0 +1,61 @@
+[net]
+mtu=1300
+
+[sip]
+sip_port=5072
+sip_tcp_port=5072
+sip_tls_port=5073
+default_proxy=0
+
+[auth_info_0]
+username=liblinphone_tester
+userid=liblinphone_tester
+passwd=secret
+realm="auth.example.org"
+
+[auth_info_1]
+username=pauline
+userid=pauline
+passwd=secret
+realm="sip.example.org"
+
+[auth_info_2]
+username=liblinphone_tester
+userid=liblinphone_tester
+passwd=secret
+realm="auth1.example.org"
+
+[auth_info_3]
+username=marie
+userid=marie
+passwd=secret
+realm="sip.example.org"
+
+[proxy_0]
+reg_proxy=sip2.linphone.org
+reg_route=sip2.linphone.org
+reg_identity=sip:pauline@sip.example.org
+reg_expires=3600
+reg_sendregister=1
+publish=0
+dial_escape_plus=0
+
+[proxy_1]
+reg_proxy=sip2.linphone.org;transport=tcp
+reg_route=sip2.linphone.org;transport=tcp
+reg_identity=sip:marie@sip.example.org
+reg_expires=3600
+reg_sendregister=1
+publish=0
+dial_escape_plus=0
+
+[proxy_2]
+reg_proxy=sip2.linphone.org
+reg_route=sip2.linphone.org
+reg_identity=sip:liblinphone_tester@auth1.example.org
+reg_expires=3600
+reg_sendregister=1
+publish=0
+dial_escape_plus=0
+
+
diff --git a/liblinphone_tester/res/raw/pauline_rc b/liblinphone_tester/res/raw/pauline_rc
new file mode 100644
index 000000000..eb588cfc6
--- /dev/null
+++ b/liblinphone_tester/res/raw/pauline_rc
@@ -0,0 +1,46 @@
+[net]
+mtu=1300
+
+[sip]
+sip_port=5072
+sip_tcp_port=5072
+sip_tls_port=5073
+default_proxy=0
+ping_with_options=0
+register_only_when_network_is_up=0
+
+[auth_info_0]
+username=pauline
+userid=pauline
+passwd=secret
+realm="sip.example.org"
+
+
+[proxy_0]
+reg_proxy=sip2.linphone.org;transport=tcp
+reg_route=sip2.linphone.org;transport=tcp;lr
+reg_identity=sip:pauline@sip.example.org
+reg_expires=3600
+reg_sendregister=1
+publish=0
+dial_escape_plus=0
+
+#[friend_0]
+#url="Mariette"
+#pol=accept
+#subscribe=0
+
+[rtp]
+audio_rtp_port=8090
+video_rtp_port=8092
+
+[video]
+display=0
+capture=0
+show_local=0
+size=vga
+enabled=0
+self_view=0
+automatically_initiate=0
+automatically_accept=0
+device=StaticImage: Static picture
\ No newline at end of file
diff --git a/liblinphone_tester/res/values-v11/styles.xml b/liblinphone_tester/res/values-v11/styles.xml
new file mode 100644
index 000000000..541752f6e
--- /dev/null
+++ b/liblinphone_tester/res/values-v11/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/liblinphone_tester/res/values-v14/styles.xml b/liblinphone_tester/res/values-v14/styles.xml
new file mode 100644
index 000000000..f20e01501
--- /dev/null
+++ b/liblinphone_tester/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/liblinphone_tester/res/values/strings.xml b/liblinphone_tester/res/values/strings.xml
new file mode 100644
index 000000000..973b9fab5
--- /dev/null
+++ b/liblinphone_tester/res/values/strings.xml
@@ -0,0 +1,8 @@
+
+
+
+ liblinphone tester
+ Start
+ Settings
+
+
\ No newline at end of file
diff --git a/liblinphone_tester/res/values/styles.xml b/liblinphone_tester/res/values/styles.xml
new file mode 100644
index 000000000..4a10ca492
--- /dev/null
+++ b/liblinphone_tester/res/values/styles.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/liblinphone_tester/src/org/linphone/tester/MainActivity.java b/liblinphone_tester/src/org/linphone/tester/MainActivity.java
new file mode 100644
index 000000000..b812fac0f
--- /dev/null
+++ b/liblinphone_tester/src/org/linphone/tester/MainActivity.java
@@ -0,0 +1,97 @@
+package org.linphone.tester;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import android.os.Bundle;
+import android.app.Activity;
+import android.view.Menu;
+import android.view.View;
+import android.widget.TextView;
+
+import org.linphone.tester.Tester;
+
+public class MainActivity extends Activity {
+ static public MainActivity instance = null;
+ static public Tester tester = new Tester();
+ String mLogs = "";
+ MainThread mThread;
+
+ private class MainThread extends Thread {
+ MainActivity mActivity;
+ public MainThread(MainActivity activity) {
+ mActivity = activity;
+ }
+ @Override
+ public void run() {
+ String path = mActivity.getFilesDir().getAbsolutePath();
+ tester.run(new String[]{"tester", "--verbose", "--config", path});
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.done();
+ }
+ });
+ }
+ }
+
+ private void copyFromPackage(int ressourceId,String target) throws IOException{
+ FileOutputStream lOutputStream = openFileOutput (target, 0);
+ InputStream lInputStream = getResources().openRawResource(ressourceId);
+ int readByte;
+ byte[] buff = new byte[8048];
+ while (( readByte = lInputStream.read(buff)) != -1) {
+ lOutputStream.write(buff,0, readByte);
+ }
+ lOutputStream.flush();
+ lOutputStream.close();
+ lInputStream.close();
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ try {
+ copyFromPackage(R.raw.laure_rc, new File("laure_rc").getName());
+ copyFromPackage(R.raw.marie_rc, new File("marie_rc").getName());
+ copyFromPackage(R.raw.multi_account_lrc, new File("multi_account_lrc").getName());
+ copyFromPackage(R.raw.pauline_rc, new File("pauline_rc").getName());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ super.onCreate(savedInstanceState);
+ instance = this;
+ setContentView(R.layout.activity_main);
+ ((TextView)findViewById(R.id.textView1)).setText(mLogs);
+ if(mThread == null || !mThread.isAlive()) {
+ findViewById(R.id.button1).setEnabled(true);
+ } else {
+ findViewById(R.id.button1).setEnabled(true);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.activity_main, menu);
+ return true;
+ }
+
+ public void onBtnClicked(View v) {
+ mLogs = "";
+ ((TextView)findViewById(R.id.textView1)).setText(mLogs);
+ findViewById(R.id.button1).setEnabled(false);
+ mThread = new MainThread(this);
+ mThread.start();
+ }
+
+ public void addLog(int level, String message) {
+ mLogs += message;
+ ((TextView)findViewById(R.id.textView1)).append(message);
+ }
+
+ public void done() {
+ findViewById(R.id.button1).setEnabled(true);
+ }
+}
diff --git a/liblinphone_tester/src/org/linphone/tester/Tester.java b/liblinphone_tester/src/org/linphone/tester/Tester.java
new file mode 100644
index 000000000..d45cd1a7f
--- /dev/null
+++ b/liblinphone_tester/src/org/linphone/tester/Tester.java
@@ -0,0 +1,106 @@
+package org.linphone.tester;
+
+import org.linphone.mediastream.CpuUtils;
+import org.linphone.mediastream.Version;
+
+import android.util.Log;
+
+public class Tester {
+ public static String TAG = "liblinphone-tester";
+ private static boolean loadOptionalLibrary(String s) {
+ try {
+ System.loadLibrary(s);
+ return true;
+ } catch (Throwable e) {
+ Log.w("Unable to load optional library lib", s);
+ }
+ return false;
+ }
+
+ public static boolean hasNeonInCpuFeatures()
+ {
+ CpuUtils cpu = new CpuUtils();
+ return cpu.isCpuNeon();
+ }
+
+ public static boolean isArmv7()
+ {
+ return System.getProperty("os.arch").contains("armv7");
+ }
+
+ static {
+ // FFMPEG (audio/video)
+ loadOptionalLibrary("avutil");
+ loadOptionalLibrary("swscale");
+ loadOptionalLibrary("avcore");
+
+ System.loadLibrary("neon");
+
+ if (!hasNeonInCpuFeatures()) {
+ boolean noNeonLibrariesLoaded = loadOptionalLibrary("avcodecnoneon");
+ if (!noNeonLibrariesLoaded) {
+ loadOptionalLibrary("avcodec");
+ }
+ } else {
+ loadOptionalLibrary("avcodec");
+ }
+
+ // OPENSSL (cryptography)
+ // lin prefix avoids collision with libs in /system/lib
+ loadOptionalLibrary("lincrypto");
+ loadOptionalLibrary("linssl");
+
+ // Secure RTP and key negotiation
+ loadOptionalLibrary("srtp");
+ loadOptionalLibrary("zrtpcpp"); // GPLv3+
+
+ // Tunnel
+ loadOptionalLibrary("tunnelclient");
+
+ // g729 A implementation
+ loadOptionalLibrary("bcg729");
+
+ System.loadLibrary("cunit");
+
+ //Main library
+ if (!hasNeonInCpuFeatures()) {
+ try {
+ if (!isArmv7() && !Version.isX86()) {
+ System.loadLibrary("linphonearmv5");
+ System.loadLibrary("linphone_testerarmv5");
+ } else {
+ System.loadLibrary("linphonenoneon");
+ System.loadLibrary("linphone_testernoneon");
+ }
+ Log.w("linphone", "No-neon liblinphone loaded");
+ } catch (UnsatisfiedLinkError ule) {
+ Log.w("linphone", "Failed to load no-neon liblinphone, loading neon liblinphone");
+ System.loadLibrary("linphone");
+ System.loadLibrary("linphone_tester");
+ }
+ } else {
+ System.loadLibrary("linphone");
+ System.loadLibrary("linphone_tester");
+ }
+
+ Version.dumpCapabilities();
+ }
+
+ public native int run(String args[]);
+
+ public void printLog(final int level, final String message) {
+ MainActivity.instance.runOnUiThread(new Runnable() {
+ public void run() {
+ MainActivity.instance.addLog(level, message);
+ }
+ });
+ switch(level) {
+ case 0:
+ android.util.Log.i(TAG, message);
+ break;
+ case 1:
+ android.util.Log.e(TAG, message);
+ break;
+ }
+ }
+}
diff --git a/submodules/externals/build/cunit/Android.mk b/submodules/externals/build/cunit/Android.mk
new file mode 100644
index 000000000..68e1cc003
--- /dev/null
+++ b/submodules/externals/build/cunit/Android.mk
@@ -0,0 +1,24 @@
+BUILD_PATH := $(call my-dir)
+LOCAL_PATH := $(call my-dir)/../../cunit
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ CUnit/Sources/Framework/CUError.c \
+ CUnit/Sources/Framework/MyMem.c \
+ CUnit/Sources/Framework/TestDB.c \
+ CUnit/Sources/Framework/TestRun.c \
+ CUnit/Sources/Framework/Util.c \
+ CUnit/Sources/Basic/Basic.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/CUnit/Headers/ \
+
+LOCAL_EXPORT_C_INCLUDES := \
+ $(BUILD_PATH) \
+
+LOCAL_MODULE := cunit
+LOCAL_LDLIBS := -llog
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/submodules/externals/cunit b/submodules/externals/cunit
new file mode 160000
index 000000000..1cfa64e10
--- /dev/null
+++ b/submodules/externals/cunit
@@ -0,0 +1 @@
+Subproject commit 1cfa64e1075822e3acf9663aded232dfd171dae1
diff --git a/submodules/linphone b/submodules/linphone
index 018fbdb7f..673ddcae3 160000
--- a/submodules/linphone
+++ b/submodules/linphone
@@ -1 +1 @@
-Subproject commit 018fbdb7f1dbb634eb99c01c6fa9cc663147dae8
+Subproject commit 673ddcae3da7925b841d91b6076e81e8fd8f82e0